summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitlab/CODEOWNERS2
-rw-r--r--CHANGELOG.md60
-rw-r--r--GITLAB_PAGES_VERSION2
-rw-r--r--Gemfile4
-rw-r--r--Gemfile.lock21
-rw-r--r--PROCESS.md27
-rw-r--r--app/assets/javascripts/commit/pipelines/pipelines_table.vue2
-rw-r--r--app/assets/javascripts/diffs/components/commit_item.vue2
-rw-r--r--app/assets/javascripts/environments/components/container.vue2
-rw-r--r--app/assets/javascripts/environments/mixins/environments_mixin.js2
-rw-r--r--app/assets/javascripts/gl_dropdown.js2
-rw-r--r--app/assets/javascripts/ide/components/ide.vue2
-rw-r--r--app/assets/javascripts/ide/components/ide_status_bar.vue16
-rw-r--r--app/assets/javascripts/ide/components/ide_status_list.vue23
-rw-r--r--app/assets/javascripts/lib/utils/invalid_url.js6
-rw-r--r--app/assets/javascripts/lib/utils/url_utility.js12
-rw-r--r--app/assets/javascripts/monitoring/components/charts/area.vue5
-rw-r--r--app/assets/javascripts/monitoring/components/dashboard.vue39
-rw-r--r--app/assets/javascripts/monitoring/monitoring_bundle.js5
-rw-r--r--app/assets/javascripts/monitoring/stores/actions.js90
-rw-r--r--app/assets/javascripts/monitoring/stores/mutation_types.js3
-rw-r--r--app/assets/javascripts/monitoring/stores/mutations.js53
-rw-r--r--app/assets/javascripts/monitoring/stores/state.js5
-rw-r--r--app/assets/javascripts/monitoring/stores/utils.js16
-rw-r--r--app/assets/javascripts/pipelines/components/graph/job_name_component.vue2
-rw-r--r--app/assets/javascripts/pipelines/components/pipelines.vue2
-rw-r--r--app/assets/javascripts/registry/components/table_registry.vue2
-rw-r--r--app/assets/javascripts/repository/components/table/index.vue1
-rw-r--r--app/assets/javascripts/repository/components/table/row.vue12
-rw-r--r--app/assets/javascripts/repository/queries/getFiles.graphql1
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/mr_widget_header.vue2
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_auto_merge_enabled.vue (renamed from app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_merge_when_pipeline_succeeds.vue)16
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_conflicts.vue2
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/states/ready_to_merge.vue47
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/constants.js10
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/mixins/auto_merge.js15
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/mixins/ready_to_merge.js6
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/mr_widget_options.vue24
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/stores/mr_widget_store.js22
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/stores/state_maps.js2
-rw-r--r--app/assets/javascripts/vue_shared/components/commit.vue10
-rw-r--r--app/assets/javascripts/vue_shared/components/pagination/constants.js9
-rw-r--r--app/assets/javascripts/vue_shared/components/pagination/graphql_pagination.vue47
-rw-r--r--app/assets/javascripts/vue_shared/components/pagination/table_pagination.vue (renamed from app/assets/javascripts/vue_shared/components/table_pagination.vue)18
-rw-r--r--app/assets/stylesheets/bootstrap_migration.scss5
-rw-r--r--app/assets/stylesheets/components/avatar.scss9
-rw-r--r--app/assets/stylesheets/components/popover.scss95
-rw-r--r--app/assets/stylesheets/framework/feature_highlight.scss7
-rw-r--r--app/assets/stylesheets/framework/issue_box.scss4
-rw-r--r--app/assets/stylesheets/framework/mixins.scss11
-rw-r--r--app/assets/stylesheets/framework/typography.scss1
-rw-r--r--app/assets/stylesheets/framework/variables.scss6
-rw-r--r--app/assets/stylesheets/page_bundles/ide.scss15
-rw-r--r--app/assets/stylesheets/pages/commits.scss8
-rw-r--r--app/assets/stylesheets/pages/diff.scss2
-rw-r--r--app/assets/stylesheets/pages/issuable.scss3
-rw-r--r--app/assets/stylesheets/pages/milestone.scss21
-rw-r--r--app/assets/stylesheets/pages/notes.scss2
-rw-r--r--app/assets/stylesheets/pages/prometheus.scss1
-rw-r--r--app/controllers/admin/application_settings_controller.rb6
-rw-r--r--app/controllers/import/fogbugz_controller.rb8
-rw-r--r--app/controllers/profiles/emails_controller.rb4
-rw-r--r--app/controllers/projects/environments/prometheus_api_controller.rb2
-rw-r--r--app/controllers/projects/merge_requests_controller.rb18
-rw-r--r--app/finders/issuable_finder.rb8
-rw-r--r--app/graphql/types/tree/blob_type.rb3
-rw-r--r--app/helpers/environments_helper.rb1
-rw-r--r--app/models/broadcast_message.rb11
-rw-r--r--app/models/ci/pipeline_schedule.rb3
-rw-r--r--app/models/clusters/cluster.rb1
-rw-r--r--app/models/clusters/platforms/kubernetes.rb1
-rw-r--r--app/models/concerns/prometheus_adapter.rb1
-rw-r--r--app/models/concerns/reactive_caching.rb4
-rw-r--r--app/models/label.rb1
-rw-r--r--app/models/merge_request.rb36
-rw-r--r--app/models/notification_recipient.rb5
-rw-r--r--app/models/project.rb2
-rw-r--r--app/models/project_ci_cd_setting.rb2
-rw-r--r--app/models/project_statistics.rb2
-rw-r--r--app/policies/project_policy.rb1
-rw-r--r--app/presenters/blob_presenter.rb2
-rw-r--r--app/presenters/ci/build_runner_presenter.rb4
-rw-r--r--app/services/auto_merge/base_service.rb11
-rw-r--r--app/services/auto_merge_service.rb6
-rw-r--r--app/services/ci/pipeline_schedule_service.rb2
-rw-r--r--app/services/merge_requests/base_service.rb4
-rw-r--r--app/services/merge_requests/close_service.rb4
-rw-r--r--app/services/merge_requests/merge_to_ref_service.rb20
-rw-r--r--app/services/merge_requests/mergeability_check_service.rb82
-rw-r--r--app/services/merge_requests/refresh_service.rb6
-rw-r--r--app/services/merge_requests/update_service.rb2
-rw-r--r--app/services/projects/fork_service.rb6
-rw-r--r--app/services/service_response.rb15
-rw-r--r--app/views/admin/application_settings/_performance_bar.html.haml2
-rw-r--r--app/views/admin/application_settings/_visibility_and_access.html.haml1
-rw-r--r--app/views/admin/application_settings/metrics_and_profiling.html.haml2
-rw-r--r--app/views/layouts/nav/sidebar/_project.html.haml2
-rw-r--r--app/views/profiles/emails/index.html.haml46
-rw-r--r--app/views/profiles/keys/_form.html.haml4
-rw-r--r--app/views/projects/branches/_branch.html.haml2
-rw-r--r--app/views/projects/commit/_commit_box.html.haml2
-rw-r--r--app/views/shared/_email_with_badge.html.haml2
-rw-r--r--app/views/shared/milestones/_deprecation_message.html.haml1
-rw-r--r--changelogs/archive.md36
-rw-r--r--changelogs/unreleased/33064-add-labels-to-note-event-payload.yml5
-rw-r--r--changelogs/unreleased/5615-non-admins-only-archieve-ce.yml5
-rw-r--r--changelogs/unreleased/58433-email-notifications-do-not-work-properly-issue-due-date.yml5
-rw-r--r--changelogs/unreleased/58984-doc-missing-milestones-and-labels-links.yml5
-rw-r--r--changelogs/unreleased/59651-remove-unnecessary-decimal-places-on-chart-axes.yml5
-rw-r--r--changelogs/unreleased/61072-link-to-user-profile-not-distinguishable-on-latest-commit-widget.yml5
-rw-r--r--changelogs/unreleased/61246-fix-label-click-scroll-to-top.yml5
-rw-r--r--changelogs/unreleased/62144-fix-option-dropdown-button-size.yml5
-rw-r--r--changelogs/unreleased/62154-fe-create-fix-long-branch-name-in-dropdown.yml6
-rw-r--r--changelogs/unreleased/62300-target-area-for-dropdown-list-items-is-too-small-on-metrics-dashboard.yml5
-rw-r--r--changelogs/unreleased/62713-fix-uninstalling-cluster-apps.yml5
-rw-r--r--changelogs/unreleased/62788-clean-up-pagination.yml5
-rw-r--r--changelogs/unreleased/62788-graphql-pagination.yml5
-rw-r--r--changelogs/unreleased/62974-follow-up-from-wip-align-merge-request-icons-and-text.yml5
-rw-r--r--changelogs/unreleased/9186-implement-atmtwps-state-to-mr-widget.yml5
-rw-r--r--changelogs/unreleased/ac-63020-typeerror-nil-can-t-be-coerced-into-integer.yml5
-rw-r--r--changelogs/unreleased/add-lfs-blob-ids-to-tree-type.yml5
-rw-r--r--changelogs/unreleased/allow-emoji-in-references.yml5
-rw-r--r--changelogs/unreleased/cancel-auto-merge-when-branch-is-changed.yml5
-rw-r--r--changelogs/unreleased/expose-project-git-depth-via-api.yml5
-rw-r--r--changelogs/unreleased/fe-fix-gl-dropdown-scrolling-to-top.yml5
-rw-r--r--changelogs/unreleased/fix-diverged-branch-locals.yml5
-rw-r--r--changelogs/unreleased/fix-issue-mr-badge.yml5
-rw-r--r--changelogs/unreleased/fix-pipeline-schedule-owner-is-nil.yml5
-rw-r--r--changelogs/unreleased/i18n-email-of-user-profile.yml5
-rw-r--r--changelogs/unreleased/ignore-artifact-attirbutes-in-project-import-export.yml5
-rw-r--r--changelogs/unreleased/jc-migration-for-source-project-id.yml5
-rw-r--r--changelogs/unreleased/osw-avoid-encoding-errors-on-merge-to-ref-service.yml5
-rw-r--r--changelogs/unreleased/osw-fix-post-dep-migration-with-timeout.yml5
-rw-r--r--changelogs/unreleased/osw-sync-merge-ref-upon-mergeability-check.yml5
-rw-r--r--changelogs/unreleased/patch-65.yml5
-rw-r--r--changelogs/unreleased/revert-git-depth-for-merge-request.yml5
-rw-r--r--changelogs/unreleased/sh-add-backtrace-to-sql-queries.yml5
-rw-r--r--changelogs/unreleased/sh-fix-fogbugz-import.yml5
-rw-r--r--changelogs/unreleased/sh-fix-openid-connect-defaults.yml5
-rw-r--r--changelogs/unreleased/sh-fix-resolve-button-not-available.yml5
-rw-r--r--changelogs/unreleased/sh-fix-utf-8-encoding-resolve-conflicts.yml5
-rw-r--r--changelogs/unreleased/sh-project-import-visibility-error.yml5
-rw-r--r--changelogs/unreleased/upgrade-pages-to-v1-6-1.yml5
-rw-r--r--config/initializers/rack_timeout.rb2
-rw-r--r--config/puma.example.development.rb1
-rw-r--r--config/routes/project.rb2
-rw-r--r--db/migrate/20190604184643_fix_pool_repository_source_project_id.rb19
-rw-r--r--db/migrate/20190605104727_add_default_project_deletion_protection_to_application_settings.rb20
-rw-r--r--db/migrate/20190611161641_add_target_project_id_to_merge_trains.rb14
-rw-r--r--db/post_migrate/20190528180441_enqueue_reset_merge_status.rb15
-rw-r--r--db/schema.rb7
-rw-r--r--doc/administration/high_availability/README.md3
-rw-r--r--doc/administration/high_availability/nfs.md8
-rw-r--r--doc/administration/index.md2
-rw-r--r--doc/administration/monitoring/performance/index.md2
-rw-r--r--doc/administration/monitoring/prometheus/gitlab_metrics.md1
-rw-r--r--doc/administration/repository_storage_types.md5
-rw-r--r--doc/api/merge_requests.md22
-rw-r--r--doc/api/projects.md8
-rw-r--r--doc/ci/README.md11
-rw-r--r--doc/ci/ci_cd_for_external_repos/github_integration.md22
-rw-r--r--doc/ci/ci_cd_for_external_repos/index.md4
-rw-r--r--doc/ci/docker/using_docker_build.md2
-rw-r--r--doc/ci/docker/using_docker_images.md95
-rw-r--r--doc/ci/environments.md4
-rw-r--r--doc/ci/examples/README.md71
-rw-r--r--doc/ci/examples/artifactory_and_gitlab/index.md5
-rw-r--r--doc/ci/examples/browser_performance.md26
-rw-r--r--doc/ci/examples/code_quality.md4
-rw-r--r--doc/ci/examples/deploy_spring_boot_to_cloud_foundry/index.md9
-rw-r--r--doc/ci/examples/deployment/README.md14
-rw-r--r--doc/ci/examples/deployment/composer-npm-deploy.md24
-rw-r--r--doc/ci/examples/devops_and_game_dev_with_gitlab_ci_cd/index.md3
-rw-r--r--doc/ci/examples/end_to_end_testing_webdriverio/index.md5
-rw-r--r--doc/ci/examples/laravel_with_gitlab_and_envoy/index.md1
-rw-r--r--doc/ci/examples/php.md12
-rw-r--r--doc/ci/examples/test-and-deploy-python-application-to-heroku.md19
-rw-r--r--doc/ci/examples/test-and-deploy-ruby-application-to-heroku.md17
-rw-r--r--doc/ci/examples/test-clojure-application.md20
-rw-r--r--doc/ci/examples/test-scala-application.md21
-rw-r--r--doc/ci/examples/test_phoenix_app_with_gitlab_ci_cd/index.md7
-rw-r--r--doc/ci/introduction/index.md3
-rw-r--r--doc/ci/metrics_reports.md5
-rw-r--r--doc/development/architecture.md21
-rw-r--r--doc/development/git_object_deduplication.md109
-rw-r--r--doc/development/gitaly.md2
-rw-r--r--doc/development/img/architecture_simplified.pngbin0 -> 61590 bytes
-rw-r--r--doc/development/new_fe_guide/development/accessibility.md1
-rw-r--r--doc/development/testing_guide/best_practices.md2
-rw-r--r--doc/development/testing_guide/end_to_end/quick_start_guide.md2
-rw-r--r--doc/gitlab-basics/README.md1
-rw-r--r--doc/install/installation.md8
-rw-r--r--doc/install/requirements.md4
-rw-r--r--doc/integration/elasticsearch.md2
-rw-r--r--doc/integration/jenkins.md5
-rw-r--r--doc/migrate_ci_to_ce/README.md19
-rw-r--r--doc/policy/maintenance.md25
-rw-r--r--doc/public_access/public_access.md53
-rw-r--r--doc/push_rules/push_rules.md29
-rw-r--r--doc/security/README.md1
-rw-r--r--doc/security/crime_vulnerability.md36
-rw-r--r--doc/security/information_exclusivity.md41
-rw-r--r--doc/security/password_length_limits.md21
-rw-r--r--doc/security/rack_attack.md26
-rw-r--r--doc/security/reset_root_password.md19
-rw-r--r--doc/security/ssh_keys_restrictions.md15
-rw-r--r--doc/security/two_factor_authentication.md15
-rw-r--r--doc/security/unlock_user.md20
-rw-r--r--doc/security/user_email_confirmation.md22
-rw-r--r--doc/security/user_file_uploads.md35
-rw-r--r--doc/security/webhooks.md52
-rw-r--r--doc/ssh/README.md14
-rw-r--r--doc/subscriptions/index.md27
-rw-r--r--doc/system_hooks/system_hooks.md24
-rw-r--r--doc/tools/email.md34
-rw-r--r--doc/topics/autodevops/index.md133
-rw-r--r--doc/topics/autodevops/quick_start_guide.md2
-rw-r--r--doc/topics/git/index.md2
-rw-r--r--doc/university/README.md88
-rw-r--r--doc/university/bookclub/booklist.md107
-rw-r--r--doc/university/bookclub/index.md11
-rw-r--r--doc/university/glossary/README.md707
-rw-r--r--doc/university/high-availability/aws/README.md393
-rw-r--r--doc/university/high-availability/aws/img/auto-scaling-det.pngbin29967 -> 0 bytes
-rw-r--r--doc/university/high-availability/aws/img/db-subnet-group.pngbin29298 -> 0 bytes
-rw-r--r--doc/university/high-availability/aws/img/ec-subnet.pngbin28405 -> 0 bytes
-rw-r--r--doc/university/high-availability/aws/img/ig-rt.pngbin12547 -> 0 bytes
-rw-r--r--doc/university/high-availability/aws/img/ig.pngbin8140 -> 0 bytes
-rw-r--r--doc/university/high-availability/aws/img/instance_specs.pngbin11522 -> 0 bytes
-rw-r--r--doc/university/high-availability/aws/img/new_vpc.pngbin15691 -> 0 bytes
-rw-r--r--doc/university/high-availability/aws/img/policies.pngbin39723 -> 0 bytes
-rw-r--r--doc/university/high-availability/aws/img/rds-net-opt.pngbin16340 -> 0 bytes
-rw-r--r--doc/university/high-availability/aws/img/rds-sec-group.pngbin11579 -> 0 bytes
-rw-r--r--doc/university/high-availability/aws/img/redis-cluster-det.pngbin23761 -> 0 bytes
-rw-r--r--doc/university/high-availability/aws/img/redis-net.pngbin27261 -> 0 bytes
-rw-r--r--doc/university/high-availability/aws/img/reference-arch2.pngbin53510 -> 0 bytes
-rw-r--r--doc/university/high-availability/aws/img/route_table.pngbin12088 -> 0 bytes
-rw-r--r--doc/university/high-availability/aws/img/subnet.pngbin17070 -> 0 bytes
-rw-r--r--doc/university/support/README.md95
-rw-r--r--doc/university/training/gitlab_flow.md15
-rw-r--r--doc/university/training/index.md32
-rw-r--r--doc/university/training/topics/additional_resources.md12
-rw-r--r--doc/university/training/topics/agile_git.md9
-rw-r--r--doc/university/training/topics/bisect.md16
-rw-r--r--doc/university/training/topics/cherry_picking.md6
-rw-r--r--doc/university/training/topics/env_setup.md5
-rw-r--r--doc/university/training/topics/explore_gitlab.md2
-rw-r--r--doc/university/training/topics/feature_branching.md8
-rw-r--r--doc/university/training/topics/getting_started.md21
-rw-r--r--doc/university/training/topics/git_add.md4
-rw-r--r--doc/university/training/topics/git_intro.md4
-rw-r--r--doc/university/training/topics/git_log.md20
-rw-r--r--doc/university/training/topics/merge_conflicts.md11
-rw-r--r--doc/university/training/topics/merge_requests.md8
-rw-r--r--doc/university/training/topics/rollback_commits.md22
-rw-r--r--doc/university/training/topics/stash.md22
-rw-r--r--doc/university/training/topics/subtree.md20
-rw-r--r--doc/university/training/topics/tags.md21
-rw-r--r--doc/university/training/topics/unstage.md8
-rw-r--r--doc/university/training/user_training.md80
-rw-r--r--doc/update/upgrading_from_source.md8
-rw-r--r--doc/user/admin_area/index.md25
-rw-r--r--doc/user/admin_area/license.md12
-rw-r--r--doc/user/admin_area/monitoring/health_check.md2
-rw-r--r--doc/user/application_security/container_scanning/index.md2
-rw-r--r--doc/user/application_security/dependency_scanning/index.md153
-rw-r--r--doc/user/application_security/sast/index.md114
-rw-r--r--doc/user/group/index.md12
-rw-r--r--doc/user/group/insights/index.md6
-rw-r--r--doc/user/group/saml_sso/scim_setup.md20
-rw-r--r--doc/user/img/markdown_inline_diffs_tags_rendered.pngbin0 -> 1804 bytes
-rw-r--r--doc/user/instance_statistics/convdev.md2
-rw-r--r--doc/user/markdown.md6
-rw-r--r--doc/user/project/cycle_analytics.md18
-rw-r--r--doc/user/project/import/github.md2
-rw-r--r--doc/user/project/index.md1
-rw-r--r--doc/user/project/insights/index.md6
-rw-r--r--doc/user/project/integrations/jira.md2
-rw-r--r--doc/user/project/integrations/webhooks.md28
-rw-r--r--doc/user/project/issues/img/comment-or-discussion.pngbin0 -> 8378 bytes
-rw-r--r--doc/user/project/issues/img/create_mr_from_issue.pngbin0 -> 21286 bytes
-rw-r--r--doc/user/project/issues/img/issues_main_view_numbered.jpgbin205803 -> 0 bytes
-rw-r--r--doc/user/project/issues/img/issues_main_view_numbered.pngbin0 -> 278285 bytes
-rw-r--r--doc/user/project/issues/img/reopen-issue.pngbin0 -> 2522 bytes
-rw-r--r--doc/user/project/issues/img/report-abuse.pngbin0 -> 1620 bytes
-rw-r--r--doc/user/project/issues/img/show-all-activity.pngbin0 -> 8119 bytes
-rw-r--r--doc/user/project/issues/index.md6
-rw-r--r--doc/user/project/issues/issue_data_and_actions.md260
-rw-r--r--doc/user/project/issues/moving_issues.md25
-rw-r--r--doc/user/project/operations/img/external_dashboard_link.pngbin0 -> 63282 bytes
-rw-r--r--doc/user/project/operations/img/external_dashboard_settings.pngbin0 -> 103474 bytes
-rw-r--r--doc/user/project/operations/index.md1
-rw-r--r--doc/user/project/operations/linking_to_an_external_dashboard.md19
-rw-r--r--doc/user/project/settings/index.md6
-rw-r--r--doc/workflow/gitlab_flow.md2
-rw-r--r--lib/api/entities.rb4
-rw-r--r--lib/api/helpers/projects_helpers.rb1
-rw-r--r--lib/api/issues.rb11
-rw-r--r--lib/api/merge_requests.rb24
-rw-r--r--lib/banzai/pipeline/gfm_pipeline.rb2
-rw-r--r--lib/gitlab/ci/templates/Serverless.gitlab-ci.yml2
-rw-r--r--lib/gitlab/cluster/puma_worker_killer_initializer.rb3
-rw-r--r--lib/gitlab/cluster/puma_worker_killer_observer.rb24
-rw-r--r--lib/gitlab/cluster/rack_timeout_observer.rb51
-rw-r--r--lib/gitlab/data_builder/note.rb1
-rw-r--r--lib/gitlab/gitaly_client/conflicts_service.rb6
-rw-r--r--lib/gitlab/gitaly_client/operation_service.rb2
-rw-r--r--lib/gitlab/graphql/loaders/batch_lfs_oid_loader.rb25
-rw-r--r--lib/gitlab/hook_data/issue_builder.rb3
-rw-r--r--lib/gitlab/import_export/import_export.yml3
-rw-r--r--lib/gitlab/import_export/relation_factory.rb3
-rw-r--r--lib/gitlab/metrics/dashboard/base_service.rb4
-rw-r--r--lib/gitlab/metrics/dashboard/processor.rb2
-rw-r--r--lib/gitlab/metrics/dashboard/stages/base_stage.rb9
-rw-r--r--lib/gitlab/metrics/dashboard/stages/endpoint_inserter.rb42
-rw-r--r--lib/gitlab/omniauth_initializer.rb6
-rw-r--r--lib/gitlab/performance_bar/peek_query_tracker.rb7
-rw-r--r--lib/gitlab/rack_timeout_observer.rb46
-rw-r--r--locale/gitlab.pot67
-rw-r--r--qa/qa/ce/strategy.rb11
-rw-r--r--qa/qa/specs/features/browser_ui/7_configure/auto_devops/create_project_with_auto_devops_spec.rb3
-rw-r--r--spec/controllers/import/fogbugz_controller_spec.rb38
-rw-r--r--spec/controllers/projects/environments/prometheus_api_controller_spec.rb4
-rw-r--r--spec/controllers/projects/merge_requests_controller_spec.rb26
-rw-r--r--spec/controllers/projects/settings/ci_cd_controller_spec.rb2
-rw-r--r--spec/features/admin/admin_settings_spec.rb8
-rw-r--r--spec/features/commits_spec.rb6
-rw-r--r--spec/features/ics/dashboard_issues_spec.rb2
-rw-r--r--spec/features/ics/group_issues_spec.rb2
-rw-r--r--spec/features/ics/project_issues_spec.rb2
-rw-r--r--spec/features/issues_spec.rb2
-rw-r--r--spec/features/merge_request/user_accepts_merge_request_spec.rb3
-rw-r--r--spec/features/merge_request/user_creates_image_diff_notes_spec.rb2
-rw-r--r--spec/features/merge_request/user_sees_diff_spec.rb3
-rw-r--r--spec/features/merge_request/user_sees_merge_widget_spec.rb4
-rw-r--r--spec/features/merge_request/user_suggests_changes_on_diff_spec.rb4
-rw-r--r--spec/features/merge_requests/user_lists_merge_requests_spec.rb2
-rw-r--r--spec/features/projects/commits/user_browses_commits_spec.rb2
-rw-r--r--spec/features/projects/features_visibility_spec.rb3
-rw-r--r--spec/features/projects/files/undo_template_spec.rb2
-rw-r--r--spec/features/projects/files/user_creates_files_spec.rb1
-rw-r--r--spec/features/projects/labels/user_removes_labels_spec.rb2
-rw-r--r--spec/features/projects/pipelines/pipeline_spec.rb2
-rw-r--r--spec/features/projects/settings/integration_settings_spec.rb2
-rw-r--r--spec/features/projects/tree/upload_file_spec.rb2
-rw-r--r--spec/features/search/user_searches_for_commits_spec.rb2
-rw-r--r--spec/features/tags/master_creates_tag_spec.rb2
-rw-r--r--spec/finders/issues_finder_spec.rb8
-rw-r--r--spec/fixtures/lib/gitlab/metrics/dashboard/schemas/metrics.json6
-rw-r--r--spec/frontend/ide/components/ide_status_list_spec.js91
-rw-r--r--spec/frontend/lib/utils/url_utility_spec.js44
-rw-r--r--spec/frontend/repository/components/table/__snapshots__/row_spec.js.snap2
-rw-r--r--spec/frontend/repository/components/table/row_spec.js13
-rw-r--r--spec/graphql/types/tree/blob_type_spec.rb2
-rw-r--r--spec/javascripts/diffs/components/commit_item_spec.js2
-rw-r--r--spec/javascripts/monitoring/charts/area_spec.js14
-rw-r--r--spec/javascripts/monitoring/dashboard_spec.js4
-rw-r--r--spec/javascripts/monitoring/mock_data.js65
-rw-r--r--spec/javascripts/monitoring/store/actions_spec.js166
-rw-r--r--spec/javascripts/monitoring/store/mutations_spec.js77
-rw-r--r--spec/javascripts/vue_mr_widget/components/states/mr_widget_auto_merge_enabled_spec.js (renamed from spec/javascripts/vue_mr_widget/components/states/mr_widget_merge_when_pipeline_succeeds_spec.js)62
-rw-r--r--spec/javascripts/vue_mr_widget/components/states/mr_widget_conflicts_spec.js75
-rw-r--r--spec/javascripts/vue_mr_widget/components/states/mr_widget_ready_to_merge_spec.js136
-rw-r--r--spec/javascripts/vue_mr_widget/mock_data.js7
-rw-r--r--spec/javascripts/vue_mr_widget/mr_widget_options_spec.js54
-rw-r--r--spec/javascripts/vue_mr_widget/stores/mr_widget_store_spec.js42
-rw-r--r--spec/javascripts/vue_shared/components/pagination/graphql_pagination_spec.js70
-rw-r--r--spec/javascripts/vue_shared/components/table_pagination_spec.js2
-rw-r--r--spec/lib/banzai/pipeline/gfm_pipeline_spec.rb23
-rw-r--r--spec/lib/gitlab/cluster/puma_worker_killer_observer_spec.rb27
-rw-r--r--spec/lib/gitlab/cluster/rack_timeout_observer_spec.rb (renamed from spec/lib/gitlab/rack_timeout_observer_spec.rb)25
-rw-r--r--spec/lib/gitlab/data_builder/note_spec.rb2
-rw-r--r--spec/lib/gitlab/gitaly_client/conflicts_service_spec.rb21
-rw-r--r--spec/lib/gitlab/gitaly_client/operation_service_spec.rb18
-rw-r--r--spec/lib/gitlab/graphql/loaders/batch_lfs_oid_loader_spec.rb23
-rw-r--r--spec/lib/gitlab/import_export/project.json5
-rw-r--r--spec/lib/gitlab/metrics/dashboard/finder_spec.rb9
-rw-r--r--spec/lib/gitlab/metrics/dashboard/processor_spec.rb28
-rw-r--r--spec/lib/gitlab/metrics/dashboard/project_dashboard_service_spec.rb2
-rw-r--r--spec/lib/gitlab/metrics/dashboard/system_dashboard_service_spec.rb2
-rw-r--r--spec/lib/gitlab/omniauth_initializer_spec.rb8
-rw-r--r--spec/migrations/enqueue_reset_merge_status_spec.rb7
-rw-r--r--spec/migrations/fix_pool_repository_source_project_id_spec.rb29
-rw-r--r--spec/models/broadcast_message_spec.rb8
-rw-r--r--spec/models/concerns/reactive_caching_spec.rb13
-rw-r--r--spec/models/merge_request_spec.rb87
-rw-r--r--spec/models/notification_recipient_spec.rb233
-rw-r--r--spec/models/project_ci_cd_setting_spec.rb12
-rw-r--r--spec/models/project_statistics_spec.rb12
-rw-r--r--spec/policies/project_policy_spec.rb2
-rw-r--r--spec/presenters/ci/build_runner_presenter_spec.rb12
-rw-r--r--spec/rack_servers/puma_spec.rb2
-rw-r--r--spec/requests/api/issues/issues_spec.rb20
-rw-r--r--spec/requests/api/merge_requests_spec.rb61
-rw-r--r--spec/requests/api/projects_spec.rb2
-rw-r--r--spec/requests/api/runner_spec.rb6
-rw-r--r--spec/services/auto_merge/base_service_spec.rb34
-rw-r--r--spec/services/auto_merge_service_spec.rb28
-rw-r--r--spec/services/ci/pipeline_schedule_service_spec.rb8
-rw-r--r--spec/services/merge_requests/merge_to_ref_service_spec.rb41
-rw-r--r--spec/services/merge_requests/mergeability_check_service_spec.rb187
-rw-r--r--spec/services/merge_requests/update_service_spec.rb12
-rw-r--r--spec/services/projects/fork_service_spec.rb8
-rw-r--r--spec/services/service_response_spec.rb16
-rw-r--r--spec/support/capybara.rb5
-rw-r--r--spec/support/features/discussion_comments_shared_example.rb2
-rw-r--r--spec/support/shared_contexts/policies/project_policy_shared_context.rb2
-rw-r--r--spec/support/shared_examples/finders/assignees_filter_shared_examples.rb6
-rw-r--r--spec/support/shared_examples/quick_actions/issuable/shrug_quick_action_shared_examples.rb2
-rw-r--r--spec/support/shared_examples/quick_actions/issuable/tableflip_quick_action_shared_examples.rb2
-rw-r--r--spec/views/notify/pipeline_failed_email.html.haml_spec.rb4
-rw-r--r--spec/views/notify/pipeline_failed_email.text.erb_spec.rb2
-rw-r--r--spec/views/notify/pipeline_success_email.html.haml_spec.rb4
-rw-r--r--spec/views/profiles/show.html.haml_spec.rb4
414 files changed, 4610 insertions, 3153 deletions
diff --git a/.gitlab/CODEOWNERS b/.gitlab/CODEOWNERS
index d49fa4a49a0..63ac5a408bd 100644
--- a/.gitlab/CODEOWNERS
+++ b/.gitlab/CODEOWNERS
@@ -3,7 +3,7 @@
*.rake @ashmckenzie @ayufan @dbalexandre @DouweM @dzaporozhets @godfat @grzesiek @mkozono @mayra-cabrera @nick.thomas @rspeicher @rymai @reprazent @smcgivern @tkuah
# Technical writing team are the default reviewers for everything in `doc/`
-/doc/ @axil @marcia
+/doc/ @axil @marcia @eread
# Frontend maintainers should see everything in `app/assets/`
app/assets/ @ClemMakesApps @fatihacet @filipa @iamphill @mikegreiling @timzallmann @kushalpandya
diff --git a/CHANGELOG.md b/CHANGELOG.md
index fd9c4df2f3f..623e5d0acb9 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,17 @@
documentation](doc/development/changelog.md) for instructions on adding your own
entry.
+## 11.11.3 (2019-06-10)
+
+### Fixed (5 changes)
+
+- Fix invalid visibility string comparison in project import. !28612
+- Remove a default git depth in Pipelines for merge requests. !28926
+- Fix connection to Tiller error while uninstalling. !29131
+- Fix label click scrolling to top. !29202
+- Make OpenID Connect work without requiring a name. !29312
+
+
## 11.11.2 (2019-06-04)
### Fixed (7 changes)
@@ -649,7 +660,7 @@ entry.
- Forbid creating discussions for users with restricted access.
- Fix leaking private repository information in API.
- Fixed ability to see private groups by users not belonging to given group.
-- Prevent releases links API to leak tag existance.
+- Prevent releases links API to leak tag existence.
- Display the correct number of MRs a user has access to.
- Block local URLs for Kubernetes integration.
- Fix arbitrary file read via diffs during import.
@@ -1008,7 +1019,7 @@ entry.
- Display SAML failure messages instead of expecting CSRF token. !24509
- Adjust vertical alignment for project visibility icons. !24511 (Martin Hobert)
- Load initUserInternalRegexPlaceholder only when required. !24522
-- Hashed Storage: `AfterRenameService` was receiving the wrong `old_path` under some circunstances. !24526
+- Hashed Storage: `AfterRenameService` was receiving the wrong `old_path` under some circumstances. !24526
- Resolve Runners IPv6 address overlaps other values. !24531
- Fix 404s with snippet uploads in object storage. !24550
- Fixed oversized custom project notification selector dropdown. !24557
@@ -1047,7 +1058,7 @@ entry.
- Update CI YAML param table with include.
- Return bottom border on MR Tabs.
- Fixes z-index and margins of archived alert in job page.
-- Fixes archived sticky top bar without perfomance bar.
+- Fixes archived sticky top bar without performance bar.
- Fixed rebase button not showing in merge request widget.
- Fixed double tooltips on note awards buttons.
- Allow suggestions to be copied and pasted as GFM.
@@ -1480,7 +1491,7 @@ entry.
- Fix deprecation: Using positional arguments in integration tests. !24009 (Jasper Maes)
- UI improvements for redesigned project lists. !24011
- Update cert-manager chart from v0.5.0 to v0.5.2. !24025 (Takuya Noguchi)
-- Hide spinner on empty activites list on user profile overview. !24063
+- Hide spinner on empty activities list on user profile overview. !24063
- Don't show Auto DevOps enabled banner for projects with CI file or CI disabled. !24067
- Update GitLab Runner Helm Chart to 0.1.43. !24083
- Fix navigation style in docs. !24090 (Takuya Noguchi)
@@ -2009,7 +2020,7 @@ entry.
- Hide all tables on Pipeline when no Jobs for the Pipeline. !18540 (Takuya Noguchi)
- Fixing count on Milestones. !21446
-- Use case insensitve username lookups. !21728 (William George)
+- Use case insensitive username lookups. !21728 (William George)
- Correctly process Bamboo API result array. !21970 (Alex Lossent)
- Fix 'merged with' UI being displayed when merge request has no merge commit. !22022
- Fix broken file name navigation on MRs. !22109
@@ -2792,7 +2803,7 @@ entry.
- Fixes SVGs for empty states in job page overflowing on mobile.
- Fix checkboxes on runner admin settings - The labels are now clickable.
- Fixed IDE file row scrolling into view when hovering.
-- Accept upload files in public/uplaods/tmp when using accelerated uploads.
+- Accept upload files in public/uploads/tmp when using accelerated uploads.
- Include correct CSS file for xterm in environments page.
- Increase padding in code blocks.
- Fix: Project deletion may not log audit events during user deletion.
@@ -3678,7 +3689,7 @@ entry.
### Fixed (69 changes, 23 of them are from the community)
-- Optimize the upload migration proces. !15947
+- Optimize the upload migration process. !15947
- Import bitbucket issues that are reported by an anonymous user. !18199 (bartl)
- Fix an issue where the notification email address would be set to an unconfirmed email address. !18474
- Stop logging email information when emails are disabled. !18521 (Marc Shaw)
@@ -3806,7 +3817,7 @@ entry.
- Add a cronworker to rescue stale live traces. !18680
- Move SquashBeforeMerge vue component. !18813 (George Tsiolis)
- Add index on runner_type for ci_runners. !18897
-- Fix CarrierWave reads local files into memoery when migrates to ObjectStorage. !19102
+- Fix CarrierWave reads local files into memory when migrates to ObjectStorage. !19102
- Remove double-checked internal id generation. !19181
- Throttle updates to Project#last_repository_updated_at. !19183
- Add background migrations for archiving legacy job traces. !19194
@@ -3897,7 +3908,7 @@ entry.
- Adjust SQL and transaction Prometheus buckets.
- Adding branches through the WebUI is handled by Gitaly.
- Remove shellout implementation for Repository checksums.
-- Refs containting sha checks are done by Gitaly.
+- Refs containing sha checks are done by Gitaly.
- Finding a wiki page is done by Gitaly by default.
- Workhorse will use Gitaly to create archives.
- Workhorse to send raw diff and patch for commits.
@@ -4101,7 +4112,7 @@ entry.
- Display active sessions and allow the user to revoke any of it. !17867 (Alexis Reigel)
- Add cron job to email users on issue due date. !17985 (Stuart Nelson)
- Rubocop rule to avoid returning from a block. !18000 (Jacopo Beschi @jacopo-beschi)
-- Add the signature verfication badge to the compare view. !18245 (Marc Shaw)
+- Add the signature verification badge to the compare view. !18245 (Marc Shaw)
- Expose Deploy Token data as environment varialbes on CI/CD jobs. !18414
- Show group id in group settings. !18482 (George Tsiolis)
- Allow admins to enforce accepting Terms of Service on an instance. !18570
@@ -4839,7 +4850,7 @@ entry.
- Override group sidebar links. !16942 (George Tsiolis)
- Avoid running `PopulateForkNetworksRange`-migration multiple times. !16988
- Resolve PrepareUntrackedUploads PostgreSQL syntax error. !17019
-- Fix monaco editor features which were incompatable with GitLab CDN settings. !17021
+- Fix monaco editor features which were incompatible with GitLab CDN settings. !17021
- Fixed error 500 when removing an identity with synced attributes and visiting the profile page. !17054
- Fix cnacel edit note button reverting changes. !42462
- For issues display time of last edit of title or description instead of time of any attribute change.
@@ -5056,7 +5067,7 @@ entry.
### Performance (2 changes)
- rework indexes on redirect_routes.
-- Remove unecessary query from labels filter.
+- Remove unnecessary query from labels filter.
## 10.4.0 (2018-01-22)
@@ -5187,7 +5198,7 @@ entry.
- Add a gitlab:tcp_check rake task. !15759
- add support for sorting in tags api. !15772 (haseebeqx)
- Add Prometheus to available Cluster applications. !15895
-- Validate file status when commiting multiple files. !15922
+- Validate file status when committing multiple files. !15922
- List of avatars should never show +1. !15972 (Jacopo Beschi @jacopo-beschi)
- Do not generate NPM links for private NPM modules in blob view. !16002 (Mario de la Ossa)
- Backport fast database lookup of SSH authorized_keys from EE. !16014
@@ -5218,7 +5229,7 @@ entry.
- Fix web ide user preferences copy and buttons. !41789
- Update redis-rack to 2.0.4.
- Import some code and functionality from gitlab-shell to improve subprocess handling.
-- Update Browse file to Choose file in all occurences.
+- Update Browse file to Choose file in all occurrences.
- Bump mysql2 gem version from 0.4.5 to 0.4.10. (asaparov)
- Use a background migration for issues.closed_at.
@@ -5353,7 +5364,7 @@ entry.
- Fix graph notes number duplication. !15696 (Vladislav Kaverin)
- Fix updateEndpoint undefined error for issue_show app root. !15698
- Change boards page boards_data absolute urls to paths. !15703
-- Using appropiate services in the API for managing forks. !15709
+- Using appropriate services in the API for managing forks. !15709
- Confirming email with invalid token should no longer generate an error. !15726
- fix #39233 - 500 in merge request. !15774 (Martin Nowak)
- Use Markdown styling for new project guidelines. !15785 (Markus Koller)
@@ -5463,7 +5474,7 @@ entry.
- Stop reloading the page when using pagination and tabs - use API calls - in Pipelines table.
- Clean up schema of the "issues" table.
- Clarify wording of protected branch settings for the default branch.
-- Update svg external depencency.
+- Update svg external dependency.
- Clean up schema of the "merge_requests" table.
@@ -5633,7 +5644,7 @@ entry.
- Fix gitlab:backup rake for hashed storage based repositories. !15400
- Fix issue where clicking a GPG verification badge would scroll to the top of the page. !15407
- Update container repository path reference and allow using double underscore. !15417
-- Fix crash when navigating to second page of the group dashbaord when there are projects and groups on the first page. !15456
+- Fix crash when navigating to second page of the group dashboard when there are projects and groups on the first page. !15456
- Fix flash errors showing up on a non configured prometheus integration. !35652
- Fix timezone bug in Pikaday and upgrade Pikaday version.
- Fix arguments Import/Export error importing project merge requests.
@@ -6183,7 +6194,7 @@ entry.
- [CHANGED] Fire hooks asynchronously when creating a new job to improve performance. !13734
- [CHANGED] Improve performance for AutocompleteController#users.json. !13754 (Hiroyuki Sato)
- [CHANGED] Update the GPG verification semantics: A GPG signature must additionally match the committer in order to be verified. !13771 (Alexis Reigel)
-- [CHANGED] Support a multi-word fuzzy seach issues/merge requests on search bar. !13780 (Hiroyuki Sato)
+- [CHANGED] Support a multi-word fuzzy search issues/merge requests on search bar. !13780 (Hiroyuki Sato)
- [CHANGED] Default LDAP config "verify_certificates" to true for security. !13915
- [CHANGED] "Share with group lock" now applies to subgroups, but owner can override setting on subgroups. !13944
- [CHANGED] Make Gitaly PostUploadPack mandatory. !13953
@@ -6882,7 +6893,7 @@ entry.
## 9.3.2 (2017-06-27)
-- API: Fix optional arugments for POST :id/variables. !12474
+- API: Fix optional arguments for POST :id/variables. !12474
- Bump premailer-rails gem to 1.9.7 and its dependencies to prevent network retrieval of assets.
## 9.3.1 (2017-06-26)
@@ -6899,7 +6910,7 @@ entry.
- Refactored gitlab:app:check into SystemCheck liberary and improve some checks. !9173
- Add an ability to cancel attaching file and redesign attaching files UI. !9431 (blackst0ne)
- Add Aliyun OSS as the backup storage provider. !9721 (Yuanfei Zhu)
-- Add suport for find_local_branches GRPC from Gitaly. !10059
+- Add support for find_local_branches GRPC from Gitaly. !10059
- Allow manual bypass of auto_sign_in_with_provider with a new param. !10187 (Maxime Besson)
- Redirect to user's keys index instead of user's index after a key is deleted in the admin. !10227 (Cyril Jouve)
- Changed Blame to Annotate in the UI to promote blameless culture. !10378 (Ilya Vassilevsky)
@@ -6978,7 +6989,7 @@ entry.
- Add tag_list param to project api. !11799 (Ivan Chernov)
- Add changelog for improved Registry description. !11816
- Automatically adjust project settings to match changes in project visibility. !11831
-- Add slugify project path to CI enviroment variables. !11838 (Ivan Chernov)
+- Add slugify project path to CI environment variables. !11838 (Ivan Chernov)
- Add all pipeline sources as special keywords to 'only' and 'except'. !11844 (Filip Krakowski)
- Allow pulling of container images using personal access tokens. !11845
- Expose import_status in Projects API. !11851 (Robin Bobbitt)
@@ -7893,7 +7904,7 @@ entry.
- Clean-up Project navigation order. !9272
- Add Runner's jobs v4 API. !9273
- Add pipeline trigger API with user permissions. !9277
-- Enhanced filter issues layout for better mobile experiance. !9280 (Pratik Borsadiya)
+- Enhanced filter issues layout for better mobile experience. !9280 (Pratik Borsadiya)
- Move babel config for instanbul to karma config. !9286 (winniehell)
- Document U2F limitations with multiple URLs. !9300
- Wrap long Project and Group titles. !9301
@@ -8074,7 +8085,7 @@ entry.
- Add badges to global dropdown.
- Changed coverage reg expression placeholder text to be more like a placeholder.
- Show members of parent groups on project members page.
-- Fix grammer issue in admin/runners.
+- Fix grammar issue in admin/runners.
- Allow slashes in slash command arguments.
- Adds paginationd and folders view to environments table.
- hide loading spinners for server-rendered sidebar fields.
@@ -8247,7 +8258,7 @@ entry.
- Allows to search within project by commit hash. (YarNayar)
- Show organisation membership and delete comment on smaller viewports, plus change comment author name to username.
- Remove turbolinks.
-- Convert pipeline action icons to svg to have them propperly positioned.
+- Convert pipeline action icons to svg to have them properly positioned.
- Remove rogue scrollbars for issue comments with inline elements.
- Align Segoe UI label text.
- Color + and - signs in diffs to increase code legibility.
@@ -8538,3 +8549,4 @@ entry.
## 8.15.8 through 0.8.0
- See [changelogs/archive.md](changelogs/archive.md)
+
diff --git a/GITLAB_PAGES_VERSION b/GITLAB_PAGES_VERSION
index dc1e644a101..9c6d6293b1a 100644
--- a/GITLAB_PAGES_VERSION
+++ b/GITLAB_PAGES_VERSION
@@ -1 +1 @@
-1.6.0
+1.6.1
diff --git a/Gemfile b/Gemfile
index c22a3191c3c..375fcaf76ce 100644
--- a/Gemfile
+++ b/Gemfile
@@ -41,7 +41,7 @@ gem 'omniauth-shibboleth', '~> 1.3.0'
gem 'omniauth-twitter', '~> 1.4'
gem 'omniauth_crowd', '~> 2.2.0'
gem 'omniauth-authentiq', '~> 0.3.3'
-gem 'omniauth_openid_connect', '~> 0.3.0'
+gem 'omniauth_openid_connect', '~> 0.3.1'
gem "omniauth-ultraauth", '~> 0.0.2'
gem 'omniauth-salesforce', '~> 1.0.5'
gem 'rack-oauth2', '~> 1.9.3'
@@ -347,7 +347,7 @@ group :development, :test do
# Generate Fake data
gem 'ffaker', '~> 2.10'
- gem 'capybara', '~> 2.18.0'
+ gem 'capybara', '~> 3.22.0'
gem 'capybara-screenshot', '~> 1.0.22'
gem 'selenium-webdriver', '~> 3.141'
diff --git a/Gemfile.lock b/Gemfile.lock
index 785a77bc202..c403f45109c 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -110,13 +110,14 @@ GEM
bundler (~> 1.2)
thor (~> 0.18)
byebug (9.1.0)
- capybara (2.18.0)
+ capybara (3.22.0)
addressable
mini_mime (>= 0.1.3)
- nokogiri (>= 1.3.3)
- rack (>= 1.0.0)
- rack-test (>= 0.5.4)
- xpath (>= 2.0, < 4.0)
+ nokogiri (~> 1.8)
+ rack (>= 1.6.0)
+ rack-test (>= 0.6.3)
+ regexp_parser (~> 1.5)
+ xpath (~> 3.2)
capybara-screenshot (1.0.22)
capybara (>= 1.0, < 4)
launchy
@@ -587,7 +588,7 @@ GEM
activesupport
nokogiri (>= 1.4.4)
omniauth (~> 1.0)
- omniauth_openid_connect (0.3.0)
+ omniauth_openid_connect (0.3.1)
addressable (~> 2.5)
omniauth (~> 1.3)
openid_connect (~> 1.1)
@@ -658,7 +659,7 @@ GEM
pry (~> 0.10)
pry-rails (0.3.6)
pry (>= 0.10.4)
- public_suffix (3.0.3)
+ public_suffix (3.1.0)
puma (3.12.0)
puma_worker_killer (0.1.0)
get_process_mem (~> 0.2)
@@ -750,7 +751,7 @@ GEM
redis-store (>= 1.2, < 2)
redis-store (1.6.0)
redis (>= 2.2, < 5)
- regexp_parser (1.4.0)
+ regexp_parser (1.5.1)
regexp_property_values (0.3.4)
representable (3.0.4)
declarative (< 0.1.0)
@@ -1040,7 +1041,7 @@ DEPENDENCIES
browser (~> 2.5)
bullet (~> 5.5.0)
bundler-audit (~> 0.5.0)
- capybara (~> 2.18.0)
+ capybara (~> 3.22.0)
capybara-screenshot (~> 1.0.22)
carrierwave (~> 1.3)
charlock_holmes (~> 0.7.5)
@@ -1159,7 +1160,7 @@ DEPENDENCIES
omniauth-twitter (~> 1.4)
omniauth-ultraauth (~> 0.0.2)
omniauth_crowd (~> 2.2.0)
- omniauth_openid_connect (~> 0.3.0)
+ omniauth_openid_connect (~> 0.3.1)
org-ruby (~> 0.9.12)
peek (~> 1.0.1)
peek-gc (~> 0.0.2)
diff --git a/PROCESS.md b/PROCESS.md
index 3c40f658070..9e971ef7531 100644
--- a/PROCESS.md
+++ b/PROCESS.md
@@ -64,7 +64,7 @@ The milestone of an issue that is currently being worked on by a community contr
should not be set to a named GitLab milestone (e.g. 11.7, 11.8), until the associated
merge request is very close to being merged, and we will likely know in which named
GitLab milestone the issue will land. There are many factors that influence when
-a community contributor finishes an issue, or even at all. So we should set this
+a community contributor finishes an issue, or even at all. So we should set this
milestone only when we have more certainty.
Note this only applies to issues currently assigned to community contributors. For
@@ -86,21 +86,12 @@ star, smile, etc.). Some good tips about code reviews can be found in our
## Feature freeze on the 7th for the release on the 22nd
-After 7th at 23:59 (Pacific Time Zone) of each month, stable branch and RC1
-of the upcoming release (to be shipped on the 22nd) is created and deployed to GitLab.com.
-The stable branch is frozen at the most recent "qualifying commit" on master.
-A "qualifying commit" is one that is pushed before the feature freeze cutoff time
-and that passes all CI jobs (green pipeline).
+The feature freeze on the 7th has been discontinued. [Transition period overview]
+describes the change to this process. During the transition period, the only guarantee that
+a change will be included in the release on the 22nd is if the change has been
+deployed to GitLab.com prior to this date.
-Merge requests may still be merged into master during this
-period, but they will go into the _next_ release, unless they are manually
-cherry-picked into the stable branch.
-
-By freezing the stable branches 2 weeks prior to a release, we reduce the risk
-of a last minute merge request potentially breaking things.
-
-Any release candidate that gets created after this date can become a final
-release, hence the name release candidate.
+[Transition period]: https://gitlab.com/gitlab-org/release/docs/blob/21cbd409dd5f157fe252f254f3e897f01908abe2/general/deploy/auto-deploy-transition.md#transition
### Feature flags
@@ -108,15 +99,15 @@ Merge requests that make changes hidden behind a feature flag, or remove an
existing feature flag because a feature is deemed stable, may be merged (and
picked into the stable branches) up to the 19th of the month. Such merge
requests should have the ~"feature flag" label assigned, and don't require a
-corresponding exception request to be created.
+corresponding exception request to be created.
-A level of common sense should be applied when deciding whether to have a feature
+A level of common sense should be applied when deciding whether to have a feature
behind a feature flag off or on by default.
The following guidelines can be applied to help make this decision:
* If the feature is not fully ready or functioning, the feature flag should be disabled by default.
-* If the feature is ready but there are concerns about performance or impact, the feature flag should be enabled by default, but
+* If the feature is ready but there are concerns about performance or impact, the feature flag should be enabled by default, but
disabled via chatops before deployment on GitLab.com environments. If the performance concern is confirmed, the final release should have the feature flag disabled by default.
* In most other cases, the feature flag can be enabled by default.
diff --git a/app/assets/javascripts/commit/pipelines/pipelines_table.vue b/app/assets/javascripts/commit/pipelines/pipelines_table.vue
index 3e01841d563..4890f99e9d1 100644
--- a/app/assets/javascripts/commit/pipelines/pipelines_table.vue
+++ b/app/assets/javascripts/commit/pipelines/pipelines_table.vue
@@ -2,7 +2,7 @@
import PipelinesService from '../../pipelines/services/pipelines_service';
import PipelineStore from '../../pipelines/stores/pipelines_store';
import pipelinesMixin from '../../pipelines/mixins/pipelines';
-import TablePagination from '../../vue_shared/components/table_pagination.vue';
+import TablePagination from '../../vue_shared/components/pagination/table_pagination.vue';
import { getParameterByName } from '../../lib/utils/common_utils';
import CIPaginationMixin from '../../vue_shared/mixins/ci_pagination_api_mixin';
diff --git a/app/assets/javascripts/diffs/components/commit_item.vue b/app/assets/javascripts/diffs/components/commit_item.vue
index bd7259ce3ee..aaa9f8b759a 100644
--- a/app/assets/javascripts/diffs/components/commit_item.vue
+++ b/app/assets/javascripts/diffs/components/commit_item.vue
@@ -91,7 +91,7 @@ export default {
<icon :size="12" name="ellipsis_h" />
</button>
- <div class="commiter">
+ <div class="committer">
<a
:href="authorUrl"
:class="authorClass"
diff --git a/app/assets/javascripts/environments/components/container.vue b/app/assets/javascripts/environments/components/container.vue
index be80661223c..f8a637138ad 100644
--- a/app/assets/javascripts/environments/components/container.vue
+++ b/app/assets/javascripts/environments/components/container.vue
@@ -1,6 +1,6 @@
<script>
import { GlLoadingIcon } from '@gitlab/ui';
-import TablePagination from '~/vue_shared/components/table_pagination.vue';
+import TablePagination from '~/vue_shared/components/pagination/table_pagination.vue';
import containerMixin from 'ee_else_ce/environments/mixins/container_mixin';
import EnvironmentTable from '../components/environments_table.vue';
diff --git a/app/assets/javascripts/environments/mixins/environments_mixin.js b/app/assets/javascripts/environments/mixins/environments_mixin.js
index a5812b173dc..31347d95a25 100644
--- a/app/assets/javascripts/environments/mixins/environments_mixin.js
+++ b/app/assets/javascripts/environments/mixins/environments_mixin.js
@@ -11,7 +11,7 @@ import Flash from '../../flash';
import eventHub from '../event_hub';
import EnvironmentsService from '../services/environments_service';
-import tablePagination from '../../vue_shared/components/table_pagination.vue';
+import tablePagination from '../../vue_shared/components/pagination/table_pagination.vue';
import environmentTable from '../components/environments_table.vue';
import tabs from '../../vue_shared/components/navigation_tabs.vue';
import container from '../components/container.vue';
diff --git a/app/assets/javascripts/gl_dropdown.js b/app/assets/javascripts/gl_dropdown.js
index 05f34391323..bdb50606a53 100644
--- a/app/assets/javascripts/gl_dropdown.js
+++ b/app/assets/javascripts/gl_dropdown.js
@@ -567,7 +567,7 @@ GitLabDropdown = (function() {
e.stopPropagation();
// This prevents automatic scrolling to the top
- if ($target.is('a')) {
+ if ($target.closest('a').length) {
return false;
}
}
diff --git a/app/assets/javascripts/ide/components/ide.vue b/app/assets/javascripts/ide/components/ide.vue
index e41b1530226..363a8f43033 100644
--- a/app/assets/javascripts/ide/components/ide.vue
+++ b/app/assets/javascripts/ide/components/ide.vue
@@ -146,7 +146,7 @@ export default {
</div>
<component :is="rightPaneComponent" v-if="currentProjectId" />
</div>
- <ide-status-bar :file="activeFile" />
+ <ide-status-bar />
<new-modal />
</article>
</template>
diff --git a/app/assets/javascripts/ide/components/ide_status_bar.vue b/app/assets/javascripts/ide/components/ide_status_bar.vue
index ce577ae85b0..206b8341aad 100644
--- a/app/assets/javascripts/ide/components/ide_status_bar.vue
+++ b/app/assets/javascripts/ide/components/ide_status_bar.vue
@@ -1,5 +1,6 @@
<script>
import { mapActions, mapState, mapGetters } from 'vuex';
+import IdeStatusList from 'ee_else_ce/ide/components/ide_status_list.vue';
import icon from '~/vue_shared/components/icon.vue';
import tooltip from '~/vue_shared/directives/tooltip';
import timeAgoMixin from '~/vue_shared/mixins/timeago';
@@ -12,18 +13,12 @@ export default {
icon,
userAvatarImage,
CiIcon,
+ IdeStatusList,
},
directives: {
tooltip,
},
mixins: [timeAgoMixin],
- props: {
- file: {
- type: Object,
- required: false,
- default: null,
- },
- },
data() {
return {
lastCommitFormatedAge: null,
@@ -125,11 +120,6 @@ export default {
>{{ lastCommitFormatedAge }}</time
>
</div>
- <div v-if="file" class="ide-status-file">{{ file.name }}</div>
- <div v-if="file" class="ide-status-file">{{ file.eol }}</div>
- <div v-if="file && !file.binary" class="ide-status-file">
- {{ file.editorRow }}:{{ file.editorColumn }}
- </div>
- <div v-if="file" class="ide-status-file">{{ file.fileLanguage }}</div>
+ <ide-status-list class="ml-auto" />
</footer>
</template>
diff --git a/app/assets/javascripts/ide/components/ide_status_list.vue b/app/assets/javascripts/ide/components/ide_status_list.vue
new file mode 100644
index 00000000000..364e3f081a1
--- /dev/null
+++ b/app/assets/javascripts/ide/components/ide_status_list.vue
@@ -0,0 +1,23 @@
+<script>
+import { mapGetters } from 'vuex';
+
+export default {
+ computed: {
+ ...mapGetters(['activeFile']),
+ },
+};
+</script>
+
+<template>
+ <div class="ide-status-list d-flex">
+ <template v-if="activeFile">
+ <div class="ide-status-file">{{ activeFile.name }}</div>
+ <div class="ide-status-file">{{ activeFile.eol }}</div>
+ <div v-if="!activeFile.binary" class="ide-status-file">
+ {{ activeFile.editorRow }}:{{ activeFile.editorColumn }}
+ </div>
+ <div class="ide-status-file">{{ activeFile.fileLanguage }}</div>
+ </template>
+ <slot></slot>
+ </div>
+</template>
diff --git a/app/assets/javascripts/lib/utils/invalid_url.js b/app/assets/javascripts/lib/utils/invalid_url.js
new file mode 100644
index 00000000000..481bd059fc9
--- /dev/null
+++ b/app/assets/javascripts/lib/utils/invalid_url.js
@@ -0,0 +1,6 @@
+/**
+ * Invalid URL that ensures we don't make a network request
+ * Can be used as a default value for URLs. Using an empty
+ * string can still result in request being made to the current page
+ */
+export default 'https://invalid';
diff --git a/app/assets/javascripts/lib/utils/url_utility.js b/app/assets/javascripts/lib/utils/url_utility.js
index b5474fc5c71..32fd0990374 100644
--- a/app/assets/javascripts/lib/utils/url_utility.js
+++ b/app/assets/javascripts/lib/utils/url_utility.js
@@ -1,3 +1,5 @@
+import { join as joinPaths } from 'path';
+
// Returns an array containing the value(s) of the
// of the key passed as an argument
export function getParameterValues(sParam) {
@@ -157,4 +159,12 @@ export function isSafeURL(url) {
}
}
-export { join as joinPaths } from 'path';
+export function getWebSocketProtocol() {
+ return window.location.protocol.replace('http', 'ws');
+}
+
+export function getWebSocketUrl(path) {
+ return `${getWebSocketProtocol()}//${joinPaths(window.location.host, path)}`;
+}
+
+export { joinPaths };
diff --git a/app/assets/javascripts/monitoring/components/charts/area.vue b/app/assets/javascripts/monitoring/components/charts/area.vue
index c43791f2426..9de4e96e4da 100644
--- a/app/assets/javascripts/monitoring/components/charts/area.vue
+++ b/app/assets/javascripts/monitoring/components/charts/area.vue
@@ -1,7 +1,7 @@
<script>
import { GlAreaChart, GlChartSeriesLabel } from '@gitlab/ui/dist/charts';
import dateFormat from 'dateformat';
-import { debounceByAnimationFrame } from '~/lib/utils/common_utils';
+import { debounceByAnimationFrame, roundOffFloat } from '~/lib/utils/common_utils';
import { getSvgIconPathContent } from '~/lib/utils/icon_utils';
import Icon from '~/vue_shared/components/icon.vue';
import { chartHeight, graphTypes, lineTypes } from '../../constants';
@@ -111,7 +111,7 @@ export default {
yAxis: {
name: this.yAxisLabel,
axisLabel: {
- formatter: value => value.toFixed(3),
+ formatter: num => roundOffFloat(num, 3).toString(),
},
},
series: this.scatterSeries,
@@ -227,6 +227,7 @@ export default {
[this.primaryColor] = chart.getOption().color;
},
onResize() {
+ if (!this.$refs.areaChart) return;
const { width } = this.$refs.areaChart.$el.getBoundingClientRect();
this.width = width;
},
diff --git a/app/assets/javascripts/monitoring/components/dashboard.vue b/app/assets/javascripts/monitoring/components/dashboard.vue
index 2314f7b80cf..d716fc211ca 100644
--- a/app/assets/javascripts/monitoring/components/dashboard.vue
+++ b/app/assets/javascripts/monitoring/components/dashboard.vue
@@ -1,18 +1,12 @@
<script>
-import {
- GlButton,
- GlDropdown,
- GlDropdownItem,
- GlModal,
- GlModalDirective,
- GlLink,
-} from '@gitlab/ui';
+import { GlButton, GlDropdown, GlDropdownItem, GlModal, GlModalDirective } from '@gitlab/ui';
import _ from 'underscore';
import { mapActions, mapState } from 'vuex';
import { s__ } from '~/locale';
import Icon from '~/vue_shared/components/icon.vue';
import '~/vue_shared/mixins/is_ee';
import { getParameterValues } from '~/lib/utils/url_utility';
+import invalidUrl from '~/lib/utils/invalid_url';
import MonitorAreaChart from './charts/area.vue';
import GraphGroup from './graph_group.vue';
import EmptyState from './empty_state.vue';
@@ -31,7 +25,6 @@ export default {
GlButton,
GlDropdown,
GlDropdownItem,
- GlLink,
GlModal,
},
directives: {
@@ -119,6 +112,11 @@ export default {
type: String,
required: true,
},
+ dashboardEndpoint: {
+ type: String,
+ required: false,
+ default: invalidUrl,
+ },
},
data() {
return {
@@ -139,13 +137,19 @@ export default {
'showEmptyState',
'environments',
'deploymentData',
+ 'metricsWithData',
+ 'useDashboardEndpoint',
]),
+ groupsWithData() {
+ return this.groups.filter(group => this.chartsWithData(group.metrics).length > 0);
+ },
},
created() {
this.setEndpoints({
metricsEndpoint: this.metricsEndpoint,
environmentsEndpoint: this.environmentsEndpoint,
deploymentsEndpoint: this.deploymentEndpoint,
+ dashboardEndpoint: this.dashboardEndpoint,
});
this.timeWindows = timeWindows;
@@ -183,7 +187,16 @@ export default {
'fetchData',
'setGettingStartedEmptyState',
'setEndpoints',
+ 'setDashboardEnabled',
]),
+ chartsWithData(charts) {
+ if (!this.useDashboardEndpoint) {
+ return charts;
+ }
+ return charts.filter(chart =>
+ chart.metrics.some(metric => this.metricsWithData.includes(metric.metric_id)),
+ );
+ },
getGraphAlerts(queries) {
if (!this.allAlerts) return {};
const metricIdsForChart = queries.map(q => q.metricId);
@@ -255,7 +268,9 @@ export default {
v-for="(value, key) in timeWindows"
:key="key"
:active="activeTimeWindow(key)"
- ><gl-link :href="setTimeWindowParameter(key)">{{ value }}</gl-link></gl-dropdown-item
+ :href="setTimeWindowParameter(key)"
+ active-class="active"
+ >{{ value }}</gl-dropdown-item
>
</gl-dropdown>
</div>
@@ -307,13 +322,13 @@ export default {
</div>
</div>
<graph-group
- v-for="(groupData, index) in groups"
+ v-for="(groupData, index) in groupsWithData"
:key="index"
:name="groupData.group"
:show-panels="showPanels"
>
<monitor-area-chart
- v-for="(graphData, graphIndex) in groupData.metrics"
+ v-for="(graphData, graphIndex) in chartsWithData(groupData.metrics)"
:key="graphIndex"
:graph-data="graphData"
:deployment-data="deploymentData"
diff --git a/app/assets/javascripts/monitoring/monitoring_bundle.js b/app/assets/javascripts/monitoring/monitoring_bundle.js
index 62c0f44c1e6..1d33537b3b2 100644
--- a/app/assets/javascripts/monitoring/monitoring_bundle.js
+++ b/app/assets/javascripts/monitoring/monitoring_bundle.js
@@ -7,6 +7,11 @@ export default (props = {}) => {
const el = document.getElementById('prometheus-graphs');
if (el && el.dataset) {
+ store.dispatch(
+ 'monitoringDashboard/setDashboardEnabled',
+ gon.features.environmentMetricsUsePrometheusEndpoint,
+ );
+
// eslint-disable-next-line no-new
new Vue({
el,
diff --git a/app/assets/javascripts/monitoring/stores/actions.js b/app/assets/javascripts/monitoring/stores/actions.js
index 63c23e8449d..49ce722b838 100644
--- a/app/assets/javascripts/monitoring/stores/actions.js
+++ b/app/assets/javascripts/monitoring/stores/actions.js
@@ -35,6 +35,21 @@ export const setEndpoints = ({ commit }, endpoints) => {
commit(types.SET_ENDPOINTS, endpoints);
};
+export const setDashboardEnabled = ({ commit }, enabled) => {
+ commit(types.SET_DASHBOARD_ENABLED, enabled);
+};
+
+export const requestMetricsDashboard = ({ commit }) => {
+ commit(types.REQUEST_METRICS_DATA);
+};
+export const receiveMetricsDashboardSuccess = ({ commit, dispatch }, { response, params }) => {
+ commit(types.RECEIVE_METRICS_DATA_SUCCESS, response.dashboard.panel_groups);
+ dispatch('fetchPrometheusMetrics', params);
+};
+export const receiveMetricsDashboardFailure = ({ commit }, error) => {
+ commit(types.RECEIVE_METRICS_DATA_FAILURE, error);
+};
+
export const requestMetricsData = ({ commit }) => commit(types.REQUEST_METRICS_DATA);
export const receiveMetricsDataSuccess = ({ commit }, data) =>
commit(types.RECEIVE_METRICS_DATA_SUCCESS, data);
@@ -56,6 +71,10 @@ export const fetchData = ({ dispatch }, params) => {
};
export const fetchMetricsData = ({ state, dispatch }, params) => {
+ if (state.useDashboardEndpoint) {
+ return dispatch('fetchDashboard', params);
+ }
+
dispatch('requestMetricsData');
return backOffRequest(() => axios.get(state.metricsEndpoint, { params }))
@@ -73,6 +92,77 @@ export const fetchMetricsData = ({ state, dispatch }, params) => {
});
};
+export const fetchDashboard = ({ state, dispatch }, params) => {
+ dispatch('requestMetricsDashboard');
+
+ return axios
+ .get(state.dashboardEndpoint, { params })
+ .then(resp => resp.data)
+ .then(response => {
+ dispatch('receiveMetricsDashboardSuccess', { response, params });
+ })
+ .catch(error => {
+ dispatch('receiveMetricsDashboardFailure', error);
+ createFlash(s__('Metrics|There was an error while retrieving metrics'));
+ });
+};
+
+function fetchPrometheusResult(prometheusEndpoint, params) {
+ return backOffRequest(() => axios.get(prometheusEndpoint, { params }))
+ .then(res => res.data)
+ .then(response => {
+ if (response.status === 'error') {
+ throw new Error(response.error);
+ }
+
+ return response.data.result;
+ });
+}
+
+/**
+ * Returns list of metrics in data.result
+ * {"status":"success", "data":{"resultType":"matrix","result":[]}}
+ *
+ * @param {metric} metric
+ */
+export const fetchPrometheusMetric = ({ commit }, { metric, params }) => {
+ const { start, end } = params;
+ const timeDiff = end - start;
+
+ const minStep = 60;
+ const queryDataPoints = 600;
+ const step = Math.max(minStep, Math.ceil(timeDiff / queryDataPoints));
+
+ const queryParams = {
+ start,
+ end,
+ step,
+ };
+
+ return fetchPrometheusResult(metric.prometheus_endpoint_path, queryParams).then(result => {
+ commit(types.SET_QUERY_RESULT, { metricId: metric.metric_id, result });
+ });
+};
+
+export const fetchPrometheusMetrics = ({ state, commit, dispatch }, params) => {
+ commit(types.REQUEST_METRICS_DATA);
+
+ const promises = [];
+ state.groups.forEach(group => {
+ group.panels.forEach(panel => {
+ panel.metrics.forEach(metric => {
+ promises.push(dispatch('fetchPrometheusMetric', { metric, params }));
+ });
+ });
+ });
+
+ return Promise.all(promises).then(() => {
+ if (state.metricsWithData.length === 0) {
+ commit(types.SET_NO_DATA_EMPTY_STATE);
+ }
+ });
+};
+
export const fetchDeploymentsData = ({ state, dispatch }) => {
if (!state.deploymentEndpoint) {
return Promise.resolve([]);
diff --git a/app/assets/javascripts/monitoring/stores/mutation_types.js b/app/assets/javascripts/monitoring/stores/mutation_types.js
index 3fd9e07fa8b..63894e83362 100644
--- a/app/assets/javascripts/monitoring/stores/mutation_types.js
+++ b/app/assets/javascripts/monitoring/stores/mutation_types.js
@@ -7,6 +7,9 @@ export const RECEIVE_DEPLOYMENTS_DATA_FAILURE = 'RECEIVE_DEPLOYMENTS_DATA_FAILUR
export const REQUEST_ENVIRONMENTS_DATA = 'REQUEST_ENVIRONMENTS_DATA';
export const RECEIVE_ENVIRONMENTS_DATA_SUCCESS = 'RECEIVE_ENVIRONMENTS_DATA_SUCCESS';
export const RECEIVE_ENVIRONMENTS_DATA_FAILURE = 'RECEIVE_ENVIRONMENTS_DATA_FAILURE';
+export const SET_QUERY_RESULT = 'SET_QUERY_RESULT';
export const SET_TIME_WINDOW = 'SET_TIME_WINDOW';
+export const SET_DASHBOARD_ENABLED = 'SET_DASHBOARD_ENABLED';
export const SET_ENDPOINTS = 'SET_ENDPOINTS';
export const SET_GETTING_STARTED_EMPTY_STATE = 'SET_GETTING_STARTED_EMPTY_STATE';
+export const SET_NO_DATA_EMPTY_STATE = 'SET_NO_DATA_EMPTY_STATE';
diff --git a/app/assets/javascripts/monitoring/stores/mutations.js b/app/assets/javascripts/monitoring/stores/mutations.js
index c1779333d75..d4b816e2717 100644
--- a/app/assets/javascripts/monitoring/stores/mutations.js
+++ b/app/assets/javascripts/monitoring/stores/mutations.js
@@ -1,5 +1,6 @@
+import Vue from 'vue';
import * as types from './mutation_types';
-import { normalizeMetrics, sortMetrics } from './utils';
+import { normalizeMetrics, sortMetrics, normalizeQueryResult } from './utils';
export default {
[types.REQUEST_METRICS_DATA](state) {
@@ -7,10 +8,24 @@ export default {
state.showEmptyState = true;
},
[types.RECEIVE_METRICS_DATA_SUCCESS](state, groupData) {
- state.groups = groupData.map(group => ({
- ...group,
- metrics: normalizeMetrics(sortMetrics(group.metrics)),
- }));
+ state.groups = groupData.map(group => {
+ let { metrics } = group;
+
+ // for backwards compatibility, and to limit Vue template changes:
+ // for each group alias panels to metrics
+ // for each panel alias metrics to queries
+ if (state.useDashboardEndpoint) {
+ metrics = group.panels.map(panel => ({
+ ...panel,
+ queries: panel.metrics,
+ }));
+ }
+
+ return {
+ ...group,
+ metrics: normalizeMetrics(sortMetrics(metrics)),
+ };
+ });
if (!state.groups.length) {
state.emptyState = 'noData';
@@ -34,12 +49,40 @@ export default {
[types.RECEIVE_ENVIRONMENTS_DATA_FAILURE](state) {
state.environments = [];
},
+ [types.SET_QUERY_RESULT](state, { metricId, result }) {
+ if (!metricId || !result || result.length === 0) {
+ return;
+ }
+
+ state.showEmptyState = false;
+
+ state.groups.forEach(group => {
+ group.metrics.forEach(metric => {
+ metric.queries.forEach(query => {
+ if (query.metric_id === metricId) {
+ state.metricsWithData.push(metricId);
+ // ensure dates/numbers are correctly formatted for charts
+ const normalizedResults = result.map(normalizeQueryResult);
+ Vue.set(query, 'result', Object.freeze(normalizedResults));
+ }
+ });
+ });
+ });
+ },
[types.SET_ENDPOINTS](state, endpoints) {
state.metricsEndpoint = endpoints.metricsEndpoint;
state.environmentsEndpoint = endpoints.environmentsEndpoint;
state.deploymentsEndpoint = endpoints.deploymentsEndpoint;
+ state.dashboardEndpoint = endpoints.dashboardEndpoint;
+ },
+ [types.SET_DASHBOARD_ENABLED](state, enabled) {
+ state.useDashboardEndpoint = enabled;
},
[types.SET_GETTING_STARTED_EMPTY_STATE](state) {
state.emptyState = 'gettingStarted';
},
+ [types.SET_NO_DATA_EMPTY_STATE](state) {
+ state.showEmptyState = true;
+ state.emptyState = 'noData';
+ },
};
diff --git a/app/assets/javascripts/monitoring/stores/state.js b/app/assets/javascripts/monitoring/stores/state.js
index 5103122612a..c33529cd588 100644
--- a/app/assets/javascripts/monitoring/stores/state.js
+++ b/app/assets/javascripts/monitoring/stores/state.js
@@ -1,12 +1,17 @@
+import invalidUrl from '~/lib/utils/invalid_url';
+
export default () => ({
hasMetrics: false,
showPanels: true,
metricsEndpoint: null,
environmentsEndpoint: null,
deploymentsEndpoint: null,
+ dashboardEndpoint: invalidUrl,
+ useDashboardEndpoint: false,
emptyState: 'gettingStarted',
showEmptyState: true,
groups: [],
deploymentData: [],
environments: [],
+ metricsWithData: [],
});
diff --git a/app/assets/javascripts/monitoring/stores/utils.js b/app/assets/javascripts/monitoring/stores/utils.js
index 9216554ecbf..84e1f1c4c20 100644
--- a/app/assets/javascripts/monitoring/stores/utils.js
+++ b/app/assets/javascripts/monitoring/stores/utils.js
@@ -58,6 +58,14 @@ export const sortMetrics = metrics =>
.sortBy('weight')
.value();
+export const normalizeQueryResult = timeSeries => ({
+ ...timeSeries,
+ values: timeSeries.values.map(([timestamp, value]) => [
+ new Date(timestamp * 1000).toISOString(),
+ Number(value),
+ ]),
+});
+
export const normalizeMetrics = metrics => {
const groupedMetrics = groupQueriesByChartInfo(metrics);
@@ -66,13 +74,7 @@ export const normalizeMetrics = metrics => {
...query,
// custom metrics do not require a label, so we should ensure this attribute is defined
label: query.label || metric.y_label,
- result: query.result.map(result => ({
- ...result,
- values: result.values.map(([timestamp, value]) => [
- new Date(timestamp * 1000).toISOString(),
- Number(value),
- ]),
- })),
+ result: (query.result || []).map(normalizeQueryResult),
}));
return {
diff --git a/app/assets/javascripts/pipelines/components/graph/job_name_component.vue b/app/assets/javascripts/pipelines/components/graph/job_name_component.vue
index 02451839330..7125790ac3d 100644
--- a/app/assets/javascripts/pipelines/components/graph/job_name_component.vue
+++ b/app/assets/javascripts/pipelines/components/graph/job_name_component.vue
@@ -25,7 +25,7 @@ export default {
};
</script>
<template>
- <span class="ci-job-name-component">
+ <span class="ci-job-name-component mw-100">
<ci-icon :status="status" />
<span class="ci-status-text text-truncate mw-70p gl-pl-1 d-inline-block align-bottom">
{{ name }}
diff --git a/app/assets/javascripts/pipelines/components/pipelines.vue b/app/assets/javascripts/pipelines/components/pipelines.vue
index 9dcea557b32..d730ef41b1a 100644
--- a/app/assets/javascripts/pipelines/components/pipelines.vue
+++ b/app/assets/javascripts/pipelines/components/pipelines.vue
@@ -4,7 +4,7 @@ import { __, sprintf, s__ } from '../../locale';
import createFlash from '../../flash';
import PipelinesService from '../services/pipelines_service';
import pipelinesMixin from '../mixins/pipelines';
-import TablePagination from '../../vue_shared/components/table_pagination.vue';
+import TablePagination from '../../vue_shared/components/pagination/table_pagination.vue';
import NavigationTabs from '../../vue_shared/components/navigation_tabs.vue';
import NavigationControls from './nav_controls.vue';
import { getParameterByName } from '../../lib/utils/common_utils';
diff --git a/app/assets/javascripts/registry/components/table_registry.vue b/app/assets/javascripts/registry/components/table_registry.vue
index 81fe0a48c06..1e4dfe76b26 100644
--- a/app/assets/javascripts/registry/components/table_registry.vue
+++ b/app/assets/javascripts/registry/components/table_registry.vue
@@ -4,7 +4,7 @@ import { GlButton, GlTooltipDirective } from '@gitlab/ui';
import { n__ } from '../../locale';
import createFlash from '../../flash';
import ClipboardButton from '../../vue_shared/components/clipboard_button.vue';
-import TablePagination from '../../vue_shared/components/table_pagination.vue';
+import TablePagination from '../../vue_shared/components/pagination/table_pagination.vue';
import Icon from '../../vue_shared/components/icon.vue';
import timeagoMixin from '../../vue_shared/mixins/timeago';
import { errorMessages, errorMessagesTypes } from '../constants';
diff --git a/app/assets/javascripts/repository/components/table/index.vue b/app/assets/javascripts/repository/components/table/index.vue
index d2198bcccfe..0357a0e44c3 100644
--- a/app/assets/javascripts/repository/components/table/index.vue
+++ b/app/assets/javascripts/repository/components/table/index.vue
@@ -135,6 +135,7 @@ export default {
:path="entry.flatPath"
:type="entry.type"
:url="entry.webUrl"
+ :lfs-oid="entry.lfsOid"
/>
</template>
</tbody>
diff --git a/app/assets/javascripts/repository/components/table/row.vue b/app/assets/javascripts/repository/components/table/row.vue
index 764882a7936..e24a5e2c447 100644
--- a/app/assets/javascripts/repository/components/table/row.vue
+++ b/app/assets/javascripts/repository/components/table/row.vue
@@ -1,8 +1,12 @@
<script>
+import { GlBadge } from '@gitlab/ui';
import { getIconName } from '../../utils/icon';
import getRefMixin from '../../mixins/get_ref';
export default {
+ components: {
+ GlBadge,
+ },
mixins: [getRefMixin],
props: {
id: {
@@ -26,6 +30,11 @@ export default {
required: false,
default: null,
},
+ lfsOid: {
+ type: String,
+ required: false,
+ default: null,
+ },
},
computed: {
routerLinkTo() {
@@ -67,6 +76,9 @@ export default {
<component :is="linkComponent" :to="routerLinkTo" :href="url" class="str-truncated">
{{ fullPath }}
</component>
+ <gl-badge v-if="lfsOid" variant="default" class="label-lfs ml-1">
+ LFS
+ </gl-badge>
<template v-if="isSubmodule">
@ <a href="#" class="commit-sha">{{ shortSha }}</a>
</template>
diff --git a/app/assets/javascripts/repository/queries/getFiles.graphql b/app/assets/javascripts/repository/queries/getFiles.graphql
index 7d92bc46455..ef924fde556 100644
--- a/app/assets/javascripts/repository/queries/getFiles.graphql
+++ b/app/assets/javascripts/repository/queries/getFiles.graphql
@@ -45,6 +45,7 @@ query getFiles(
node {
...TreeEntry
webUrl
+ lfsOid
}
}
pageInfo {
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_header.vue b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_header.vue
index 361441640e1..e20a16900d4 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_header.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_header.vue
@@ -128,7 +128,7 @@ export default {
:disabled="mr.sourceBranchRemoved"
data-target="#modal_merge_info"
data-toggle="modal"
- class="btn btn-default js-check-out-branch append-right-default"
+ class="btn btn-default js-check-out-branch append-right-8"
type="button"
>
{{ s__('mrWidget|Check out branch') }}
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_merge_when_pipeline_succeeds.vue b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_auto_merge_enabled.vue
index 88e1ccbaf35..5958c2cf87e 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_merge_when_pipeline_succeeds.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_auto_merge_enabled.vue
@@ -1,15 +1,19 @@
<script>
+import _ from 'underscore';
+import autoMergeMixin from 'ee_else_ce/vue_merge_request_widget/mixins/auto_merge';
import Flash from '../../../flash';
import statusIcon from '../mr_widget_status_icon.vue';
import MrWidgetAuthor from '../../components/mr_widget_author.vue';
import eventHub from '../../event_hub';
+import { AUTO_MERGE_STRATEGIES } from '../../constants';
export default {
- name: 'MRWidgetMergeWhenPipelineSucceeds',
+ name: 'MRWidgetAutoMergeEnabled',
components: {
MrWidgetAuthor,
statusIcon,
},
+ mixins: [autoMergeMixin],
props: {
mr: {
type: Object,
@@ -57,7 +61,7 @@ export default {
removeSourceBranch() {
const options = {
sha: this.mr.sha,
- auto_merge_strategy: 'merge_when_pipeline_succeeds',
+ auto_merge_strategy: this.mr.autoMergeStrategy,
should_remove_source_branch: true,
};
@@ -66,7 +70,7 @@ export default {
.merge(options)
.then(res => res.data)
.then(data => {
- if (data.status === 'merge_when_pipeline_succeeds') {
+ if (_.includes(AUTO_MERGE_STRATEGIES, data.status)) {
eventHub.$emit('MRWidgetUpdateRequested');
}
})
@@ -84,9 +88,9 @@ export default {
<div class="media-body">
<h4 class="d-flex align-items-start">
<span class="append-right-10">
- {{ s__('mrWidget|Set by') }}
+ <span class="js-status-text-before-author">{{ statusTextBeforeAuthor }}</span>
<mr-widget-author :author="mr.setToAutoMergeBy" />
- {{ s__('mrWidget|to be merged automatically when the pipeline succeeds') }}
+ <span class="js-status-text-after-author">{{ statusTextAfterAuthor }}</span>
</span>
<a
v-if="mr.canCancelAutomaticMerge"
@@ -97,7 +101,7 @@ export default {
@click.prevent="cancelAutomaticMerge"
>
<i v-if="isCancellingAutoMerge" class="fa fa-spinner fa-spin" aria-hidden="true"> </i>
- {{ s__('mrWidget|Cancel automatic merge') }}
+ {{ cancelButtonText }}
</a>
</h4>
<section class="mr-info-list">
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_conflicts.vue b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_conflicts.vue
index f6f445c1cef..3df4a777aca 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_conflicts.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_conflicts.vue
@@ -26,7 +26,7 @@ export default {
);
},
showResolveButton() {
- return this.mr.conflictResolutionPath && this.mr.canMerge;
+ return this.mr.conflictResolutionPath && this.mr.canPushToSourceBranch;
},
showPopover() {
return this.showResolveButton && this.mr.sourceBranchProtected;
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 615d59a7b8e..ca1b4a57717 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
@@ -1,4 +1,5 @@
<script>
+import _ from 'underscore';
import successSvg from 'icons/_icon_status_success.svg';
import warningSvg from 'icons/_icon_status_warning.svg';
import simplePoll from '~/lib/utils/simple_poll';
@@ -12,6 +13,7 @@ import SquashBeforeMerge from './squash_before_merge.vue';
import CommitsHeader from './commits_header.vue';
import CommitEdit from './commit_edit.vue';
import CommitMessageDropdown from './commit_message_dropdown.vue';
+import { AUTO_MERGE_STRATEGIES } from '../../constants';
export default {
name: 'ReadyToMerge',
@@ -30,8 +32,6 @@ export default {
data() {
return {
removeSourceBranch: this.mr.shouldRemoveSourceBranch,
- mergeWhenBuildSucceeds: false,
- autoMergeStrategy: undefined,
isMakingRequest: false,
isMergingImmediately: false,
commitMessage: this.mr.commitMessage,
@@ -42,18 +42,18 @@ export default {
};
},
computed: {
- shouldShowAutoMergeText() {
- return this.mr.isPipelineActive;
+ isAutoMergeAvailable() {
+ return !_.isEmpty(this.mr.availableAutoMergeStrategies);
},
status() {
- const { pipeline, isPipelineActive, isPipelineFailed, hasCI, ciStatus } = this.mr;
+ const { pipeline, isPipelineFailed, hasCI, ciStatus } = this.mr;
if (hasCI && !ciStatus) {
return 'failed';
+ } else if (this.isAutoMergeAvailable) {
+ return 'pending';
} else if (!pipeline) {
return 'success';
- } else if (isPipelineActive) {
- return 'pending';
} else if (isPipelineFailed) {
return 'failed';
}
@@ -87,14 +87,14 @@ export default {
mergeButtonText() {
if (this.isMergingImmediately) {
return __('Merge in progress');
- } else if (this.shouldShowAutoMergeText) {
- return __('Merge when pipeline succeeds');
+ } else if (this.isAutoMergeAvailable) {
+ return this.autoMergeText;
}
- return 'Merge';
+ return __('Merge');
},
shouldShowMergeOptionsDropdown() {
- return this.mr.isPipelineActive && !this.mr.onlyAllowMergeIfPipelineSucceeds;
+ return this.isAutoMergeAvailable && !this.mr.onlyAllowMergeIfPipelineSucceeds;
},
isRemoveSourceBranchButtonDisabled() {
return this.isMergeButtonDisabled;
@@ -104,7 +104,7 @@ export default {
return enableSquashBeforeMerge && commitsCount > 1;
},
shouldShowMergeControls() {
- return this.mr.isMergeAllowed || this.shouldShowAutoMergeText;
+ return this.mr.isMergeAllowed || this.isAutoMergeAvailable;
},
shouldShowSquashEdit() {
return this.squashBeforeMerge && this.shouldShowSquashBeforeMerge;
@@ -118,20 +118,15 @@ export default {
const { commitMessageWithDescription, commitMessage } = this.mr;
this.commitMessage = includeDescription ? commitMessageWithDescription : commitMessage;
},
- handleMergeButtonClick(mergeWhenBuildSucceeds, mergeImmediately) {
- // TODO: Remove no-param-reassign
- if (mergeWhenBuildSucceeds === undefined) {
- mergeWhenBuildSucceeds = this.mr.isPipelineActive; // eslint-disable-line no-param-reassign
- } else if (mergeImmediately) {
+ handleMergeButtonClick(useAutoMerge, mergeImmediately = false) {
+ if (mergeImmediately) {
this.isMergingImmediately = true;
}
- this.autoMergeStrategy = mergeWhenBuildSucceeds ? 'merge_when_pipeline_succeeds' : undefined;
-
const options = {
sha: this.mr.sha,
commit_message: this.commitMessage,
- auto_merge_strategy: this.autoMergeStrategy,
+ auto_merge_strategy: useAutoMerge ? this.mr.preferredAutoMergeStrategy : undefined,
should_remove_source_branch: this.removeSourceBranch === true,
squash: this.squashBeforeMerge,
squash_commit_message: this.squashCommitMessage,
@@ -144,7 +139,7 @@ export default {
.then(data => {
const hasError = data.status === 'failed' || data.status === 'hook_validation_error';
- if (data.status === 'merge_when_pipeline_succeeds') {
+ if (_.includes(AUTO_MERGE_STRATEGIES, data.status)) {
eventHub.$emit('MRWidgetUpdateRequested');
} else if (data.status === 'success') {
this.initiateMergePolling();
@@ -242,13 +237,13 @@ export default {
:class="mergeButtonClass"
type="button"
class="qa-merge-button"
- @click="handleMergeButtonClick()"
+ @click="handleMergeButtonClick(isAutoMergeAvailable)"
>
<i v-if="isMakingRequest" class="fa fa-spinner fa-spin" aria-hidden="true"></i>
{{ mergeButtonText }}
</button>
<button
- v-if="shouldShowMergeOptionsDropdown"
+ v-if="isAutoMergeAvailable"
:disabled="isMergeButtonDisabled"
type="button"
class="btn btn-sm btn-info dropdown-toggle js-merge-moment"
@@ -264,15 +259,13 @@ export default {
>
<li>
<a
- class="merge_when_pipeline_succeeds qa-merge-when-pipeline-succeeds-option"
+ class="auto_merge_enabled qa-merge-when-pipeline-succeeds-option"
href="#"
@click.prevent="handleMergeButtonClick(true)"
>
<span class="media">
<span class="merge-opt-icon" aria-hidden="true" v-html="successSvg"></span>
- <span class="media-body merge-opt-title">{{
- __('Merge when pipeline succeeds')
- }}</span>
+ <span class="media-body merge-opt-title">{{ autoMergeText }}</span>
</span>
</a>
</li>
diff --git a/app/assets/javascripts/vue_merge_request_widget/constants.js b/app/assets/javascripts/vue_merge_request_widget/constants.js
index 0a29d55fbd6..3e65bdf0cb0 100644
--- a/app/assets/javascripts/vue_merge_request_widget/constants.js
+++ b/app/assets/javascripts/vue_merge_request_widget/constants.js
@@ -3,3 +3,13 @@ export const DANGER = 'danger';
export const WARNING_MESSAGE_CLASS = 'warning_message';
export const DANGER_MESSAGE_CLASS = 'danger_message';
+
+export const MWPS_MERGE_STRATEGY = 'merge_when_pipeline_succeeds';
+export const ATMTWPS_MERGE_STRATEGY = 'add_to_merge_train_when_pipeline_succeeds';
+export const MT_MERGE_STRATEGY = 'merge_train';
+
+export const AUTO_MERGE_STRATEGIES = [
+ MWPS_MERGE_STRATEGY,
+ ATMTWPS_MERGE_STRATEGY,
+ MT_MERGE_STRATEGY,
+];
diff --git a/app/assets/javascripts/vue_merge_request_widget/mixins/auto_merge.js b/app/assets/javascripts/vue_merge_request_widget/mixins/auto_merge.js
new file mode 100644
index 00000000000..23e140623cc
--- /dev/null
+++ b/app/assets/javascripts/vue_merge_request_widget/mixins/auto_merge.js
@@ -0,0 +1,15 @@
+import { s__ } from '~/locale';
+
+export default {
+ computed: {
+ statusTextBeforeAuthor() {
+ return s__('mrWidget|Set by');
+ },
+ statusTextAfterAuthor() {
+ return s__('mrWidget|to be merged automatically when the pipeline succeeds');
+ },
+ cancelButtonText() {
+ return s__('mrWidget|Cancel automatic merge');
+ },
+ },
+};
diff --git a/app/assets/javascripts/vue_merge_request_widget/mixins/ready_to_merge.js b/app/assets/javascripts/vue_merge_request_widget/mixins/ready_to_merge.js
index b2e64506472..116d537c463 100644
--- a/app/assets/javascripts/vue_merge_request_widget/mixins/ready_to_merge.js
+++ b/app/assets/javascripts/vue_merge_request_widget/mixins/ready_to_merge.js
@@ -1,3 +1,5 @@
+import { __ } from '~/locale';
+
export default {
computed: {
isMergeButtonDisabled() {
@@ -9,5 +11,9 @@ export default {
this.mr.preventMerge,
);
},
+ autoMergeText() {
+ // MWPS is currently the only auto merge strategy available in CE
+ return __('Merge when pipeline succeeds');
+ },
},
};
diff --git a/app/assets/javascripts/vue_merge_request_widget/mr_widget_options.vue b/app/assets/javascripts/vue_merge_request_widget/mr_widget_options.vue
index d02bb2f341d..41386178a1e 100644
--- a/app/assets/javascripts/vue_merge_request_widget/mr_widget_options.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/mr_widget_options.vue
@@ -29,7 +29,7 @@ import UnresolvedDiscussionsState from './components/states/unresolved_discussio
import PipelineBlockedState from './components/states/mr_widget_pipeline_blocked.vue';
import PipelineFailedState from './components/states/pipeline_failed.vue';
import FailedToMerge from './components/states/mr_widget_failed_to_merge.vue';
-import MergeWhenPipelineSucceedsState from './components/states/mr_widget_merge_when_pipeline_succeeds.vue';
+import MrWidgetAutoMergeEnabled from './components/states/mr_widget_auto_merge_enabled.vue';
import AutoMergeFailed from './components/states/mr_widget_auto_merge_failed.vue';
import CheckingState from './components/states/mr_widget_checking.vue';
import eventHub from './event_hub';
@@ -64,7 +64,7 @@ export default {
'mr-widget-unresolved-discussions': UnresolvedDiscussionsState,
'mr-widget-pipeline-blocked': PipelineBlockedState,
'mr-widget-pipeline-failed': PipelineFailedState,
- 'mr-widget-merge-when-pipeline-succeeds': MergeWhenPipelineSucceedsState,
+ MrWidgetAutoMergeEnabled,
'mr-widget-auto-merge-failed': AutoMergeFailed,
'mr-widget-rebase': RebaseState,
SourceBranchRemovalStatus,
@@ -117,14 +117,6 @@ export default {
this.mr.mergePipelinesEnabled && this.mr.sourceProjectId !== this.mr.targetProjectId,
);
},
- showTargetBranchAdvancedError() {
- return Boolean(
- this.mr.isOpen &&
- this.mr.pipeline &&
- this.mr.pipeline.target_sha &&
- this.mr.pipeline.target_sha !== this.mr.targetBranchSha,
- );
- },
mergeError() {
return sprintf(s__('mrWidget|Merge failed: %{mergeError}. Please try again.'), {
mergeError: this.mr.mergeError,
@@ -363,18 +355,6 @@ export default {
}}
</mr-widget-alert-message>
- <mr-widget-alert-message
- v-if="showTargetBranchAdvancedError"
- type="danger"
- :help-path="mr.mergeRequestPipelinesHelpPath"
- >
- {{
- s__(
- 'mrWidget|The target branch has advanced, which invalidates the merge request pipeline. Please update the source branch and retry merging',
- )
- }}
- </mr-widget-alert-message>
-
<mr-widget-alert-message v-if="mr.mergeError" type="danger">
{{ mergeError }}
</mr-widget-alert-message>
diff --git a/app/assets/javascripts/vue_merge_request_widget/stores/mr_widget_store.js b/app/assets/javascripts/vue_merge_request_widget/stores/mr_widget_store.js
index 32badb0fb08..bfa3e7f4a59 100644
--- a/app/assets/javascripts/vue_merge_request_widget/stores/mr_widget_store.js
+++ b/app/assets/javascripts/vue_merge_request_widget/stores/mr_widget_store.js
@@ -1,7 +1,9 @@
import Timeago from 'timeago.js';
+import _ from 'underscore';
import getStateKey from 'ee_else_ce/vue_merge_request_widget/stores/get_state_key';
import { stateKey } from './state_maps';
import { formatDate } from '../../lib/utils/datetime_utility';
+import { ATMTWPS_MERGE_STRATEGY, MT_MERGE_STRATEGY, MWPS_MERGE_STRATEGY } from '../constants';
export default class MergeRequestStore {
constructor(data) {
@@ -77,6 +79,10 @@ export default class MergeRequestStore {
this.onlyAllowMergeIfPipelineSucceeds = data.only_allow_merge_if_pipeline_succeeds || false;
this.autoMergeEnabled = Boolean(data.auto_merge_enabled);
this.autoMergeStrategy = data.auto_merge_strategy;
+ this.availableAutoMergeStrategies = data.available_auto_merge_strategies;
+ this.preferredAutoMergeStrategy = MergeRequestStore.getPreferredAutoMergeStrategy(
+ this.availableAutoMergeStrategies,
+ );
this.mergePath = data.merge_path;
this.ffOnlyEnabled = data.ff_only_enabled;
this.shouldBeRebased = Boolean(data.should_be_rebased);
@@ -104,7 +110,9 @@ export default class MergeRequestStore {
this.sourceProjectFullPath = data.source_project_full_path;
this.sourceProjectId = data.source_project_id;
this.targetProjectId = data.target_project_id;
- this.mergePipelinesEnabled = data.merge_pipelines_enabled;
+ this.mergePipelinesEnabled = Boolean(data.merge_pipelines_enabled);
+ this.mergeTrainsCount = data.merge_trains_count || 0;
+ this.mergeTrainIndex = data.merge_train_index;
// Cherry-pick and Revert actions related
this.canCherryPickInCurrentMR = currentUser.can_cherry_pick_on_current_merge_request || false;
@@ -204,4 +212,16 @@ export default class MergeRequestStore {
return timeagoInstance.format(date);
}
+
+ static getPreferredAutoMergeStrategy(availableAutoMergeStrategies) {
+ if (_.includes(availableAutoMergeStrategies, ATMTWPS_MERGE_STRATEGY)) {
+ return ATMTWPS_MERGE_STRATEGY;
+ } else if (_.includes(availableAutoMergeStrategies, MT_MERGE_STRATEGY)) {
+ return MT_MERGE_STRATEGY;
+ } else if (_.includes(availableAutoMergeStrategies, MWPS_MERGE_STRATEGY)) {
+ return MWPS_MERGE_STRATEGY;
+ }
+
+ return undefined;
+ }
}
diff --git a/app/assets/javascripts/vue_merge_request_widget/stores/state_maps.js b/app/assets/javascripts/vue_merge_request_widget/stores/state_maps.js
index 48bc6a867f4..28507bba3e5 100644
--- a/app/assets/javascripts/vue_merge_request_widget/stores/state_maps.js
+++ b/app/assets/javascripts/vue_merge_request_widget/stores/state_maps.js
@@ -13,7 +13,7 @@ const stateToComponentMap = {
unresolvedDiscussions: 'mr-widget-unresolved-discussions',
pipelineBlocked: 'mr-widget-pipeline-blocked',
pipelineFailed: 'mr-widget-pipeline-failed',
- autoMergeEnabled: 'mr-widget-merge-when-pipeline-succeeds',
+ autoMergeEnabled: 'mr-widget-auto-merge-enabled',
failedToMerge: 'mr-widget-failed-to-merge',
autoMergeFailed: 'mr-widget-auto-merge-failed',
shaMismatch: 'sha-mismatch',
diff --git a/app/assets/javascripts/vue_shared/components/commit.vue b/app/assets/javascripts/vue_shared/components/commit.vue
index 3ba946e6447..a1168fa0f1e 100644
--- a/app/assets/javascripts/vue_shared/components/commit.vue
+++ b/app/assets/javascripts/vue_shared/components/commit.vue
@@ -1,6 +1,7 @@
<script>
import _ from 'underscore';
import { GlTooltipDirective, GlLink } from '@gitlab/ui';
+import TooltipOnTruncate from '~/vue_shared/components/tooltip_on_truncate.vue';
import UserAvatarLink from './user_avatar/user_avatar_link.vue';
import Icon from '../../vue_shared/components/icon.vue';
@@ -12,6 +13,7 @@ export default {
UserAvatarLink,
Icon,
GlLink,
+ TooltipOnTruncate,
},
props: {
/**
@@ -165,7 +167,7 @@ export default {
<gl-link :href="commitUrl" class="commit-sha mr-0"> {{ shortSha }} </gl-link>
<div class="commit-title flex-truncate-parent">
- <span v-if="title" class="flex-truncate-child">
+ <tooltip-on-truncate v-if="title" class="flex-truncate-child" :title="title">
<user-avatar-link
v-if="hasAuthor"
:link-href="author.path"
@@ -174,8 +176,10 @@ export default {
:tooltip-text="author.username"
class="avatar-image-container"
/>
- <gl-link :href="commitUrl" class="commit-row-message cgray"> {{ title }} </gl-link>
- </span>
+ <gl-link :href="commitUrl" class="commit-row-message cgray">
+ {{ title }}
+ </gl-link>
+ </tooltip-on-truncate>
<span v-else> Can't find HEAD commit for this branch </span>
</div>
</div>
diff --git a/app/assets/javascripts/vue_shared/components/pagination/constants.js b/app/assets/javascripts/vue_shared/components/pagination/constants.js
new file mode 100644
index 00000000000..c24b142ac7e
--- /dev/null
+++ b/app/assets/javascripts/vue_shared/components/pagination/constants.js
@@ -0,0 +1,9 @@
+import { s__ } from '~/locale';
+
+export const PAGINATION_UI_BUTTON_LIMIT = 4;
+export const UI_LIMIT = 6;
+export const SPREAD = '...';
+export const PREV = s__('Pagination|Prev');
+export const NEXT = s__('Pagination|Next');
+export const FIRST = s__('Pagination|« First');
+export const LAST = s__('Pagination|Last »');
diff --git a/app/assets/javascripts/vue_shared/components/pagination/graphql_pagination.vue b/app/assets/javascripts/vue_shared/components/pagination/graphql_pagination.vue
new file mode 100644
index 00000000000..53e473432db
--- /dev/null
+++ b/app/assets/javascripts/vue_shared/components/pagination/graphql_pagination.vue
@@ -0,0 +1,47 @@
+<script>
+import { GlButton } from '@gitlab/ui';
+import { PREV, NEXT } from '~/vue_shared/components/pagination/constants';
+
+/**
+ * Pagination Component for graphql API
+ */
+export default {
+ name: 'GraphqlPaginationComponent',
+ components: {
+ GlButton,
+ },
+ labels: {
+ prev: PREV,
+ next: NEXT,
+ },
+ props: {
+ hasNextPage: {
+ required: true,
+ type: Boolean,
+ },
+ hasPreviousPage: {
+ required: true,
+ type: Boolean,
+ },
+ },
+};
+</script>
+<template>
+ <div class="justify-content-center d-flex prepend-top-default">
+ <div class="btn-group">
+ <gl-button
+ class="js-prev-btn page-link"
+ :disabled="!hasPreviousPage"
+ @click="$emit('previousClicked')"
+ >{{ $options.labels.prev }}</gl-button
+ >
+
+ <gl-button
+ class="js-next-btn page-link"
+ :disabled="!hasNextPage"
+ @click="$emit('nextClicked')"
+ >{{ $options.labels.next }}</gl-button
+ >
+ </div>
+ </div>
+</template>
diff --git a/app/assets/javascripts/vue_shared/components/table_pagination.vue b/app/assets/javascripts/vue_shared/components/pagination/table_pagination.vue
index 9cce9a4e542..1e2d4ffa7e3 100644
--- a/app/assets/javascripts/vue_shared/components/table_pagination.vue
+++ b/app/assets/javascripts/vue_shared/components/pagination/table_pagination.vue
@@ -1,13 +1,13 @@
<script>
-import { s__ } from '../../locale';
-
-const PAGINATION_UI_BUTTON_LIMIT = 4;
-const UI_LIMIT = 6;
-const SPREAD = '...';
-const PREV = s__('Pagination|Prev');
-const NEXT = s__('Pagination|Next');
-const FIRST = s__('Pagination|« First');
-const LAST = s__('Pagination|Last »');
+import {
+ PAGINATION_UI_BUTTON_LIMIT,
+ UI_LIMIT,
+ SPREAD,
+ PREV,
+ NEXT,
+ FIRST,
+ LAST,
+} from '~/vue_shared/components/pagination/constants';
export default {
props: {
diff --git a/app/assets/stylesheets/bootstrap_migration.scss b/app/assets/stylesheets/bootstrap_migration.scss
index 7f6384f4eea..802d58779d0 100644
--- a/app/assets/stylesheets/bootstrap_migration.scss
+++ b/app/assets/stylesheets/bootstrap_migration.scss
@@ -147,11 +147,6 @@ table {
pointer-events: none;
}
-.popover,
-.popover-header {
- font-size: 14px;
-}
-
@each $breakpoint in map-keys($grid-breakpoints) {
@include media-breakpoint-up($breakpoint) {
$infix: breakpoint-infix($breakpoint, $grid-breakpoints);
diff --git a/app/assets/stylesheets/components/avatar.scss b/app/assets/stylesheets/components/avatar.scss
index 1afa5ed90f4..8e9650cdf34 100644
--- a/app/assets/stylesheets/components/avatar.scss
+++ b/app/assets/stylesheets/components/avatar.scss
@@ -191,12 +191,5 @@ $identicon-backgrounds: $identicon-red, $identicon-purple, $identicon-indigo, $i
}
.avatar-counter {
- background-color: $gray-darkest;
- color: $white-light;
- border: 1px solid $gray-normal;
- border-radius: 1em;
- font-family: $regular-font;
- font-size: 9px;
- line-height: 16px;
- text-align: center;
+ @include avatar-counter();
}
diff --git a/app/assets/stylesheets/components/popover.scss b/app/assets/stylesheets/components/popover.scss
index 774be9ef588..58aaca93160 100644
--- a/app/assets/stylesheets/components/popover.scss
+++ b/app/assets/stylesheets/components/popover.scss
@@ -1,37 +1,98 @@
.popover {
- min-width: 300px;
-
- .popover-body .user-popover {
- padding: $gl-padding-8;
- font-size: $gl-font-size-small;
- line-height: $gl-line-height;
-
- .category-icon {
- color: $gray-600;
- }
- }
+ max-width: $popover-max-width;
+ border: 1px solid $gray-200;
+ box-shadow: 0 2px 3px 1px $gray-200;
+ font-size: $gl-font-size-small;
+ /**
+ * Blue popover variation
+ */
&.blue {
background-color: $blue-600;
+ border-color: $blue-600;
.popover-body {
color: $white-light;
}
&.bs-popover-bottom {
+ .arrow::before,
.arrow::after {
border-bottom-color: $blue-600;
}
}
&.bs-popover-top {
+ .arrow::before,
.arrow::after {
border-top-color: $blue-600;
}
}
+
+ &.bs-popover-right {
+ .arrow::after,
+ .arrow::before {
+ border-right-color: $blue-600;
+ }
+ }
+
+ &.bs-popover-left {
+ .arrow::before,
+ .arrow::after {
+ border-left-color: $blue-600;
+ }
+ }
+ }
+}
+
+.bs-popover-top {
+ /* When popover position is top, the arrow is translated 1 pixel
+ * due to the box-shadow include in our custom styles.
+ */
+ > .arrow::before {
+ border-top-color: $gray-200;
+ bottom: 1px;
+ }
+
+ > .arrow::after {
+ bottom: 2px;
+ }
+}
+
+.bs-popover-bottom {
+ > .arrow::before {
+ border-bottom-color: $gray-200;
+ }
+
+ > .popover-header::before {
+ border-color: $white-light;
+ }
+}
+
+.bs-popover-right > .arrow::before {
+ border-right-color: $gray-200;
+}
+
+.bs-popover-left > .arrow::before {
+ border-left-color: $gray-200;
+}
+
+.popover-header {
+ background-color: $white-light;
+ font-size: $gl-font-size-small;
+}
+
+.popover-body {
+ padding: $gl-padding $gl-padding-12;
+
+ > .popover-hr {
+ margin: $gl-padding 0;
}
}
+/**
+* mr_popover component
+*/
.mr-popover {
.text-secondary {
font-size: 12px;
@@ -58,6 +119,18 @@
}
}
+/**
+* user_popover component
+*/
+.user-popover {
+ padding: $gl-padding-8;
+ line-height: $gl-line-height;
+
+ .category-icon {
+ color: $gray-600;
+ }
+}
+
.onboarding-welcome-page {
.popover {
min-width: auto;
diff --git a/app/assets/stylesheets/framework/feature_highlight.scss b/app/assets/stylesheets/framework/feature_highlight.scss
index 85cabf43e9e..f9b167669a6 100644
--- a/app/assets/stylesheets/framework/feature_highlight.scss
+++ b/app/assets/stylesheets/framework/feature_highlight.scss
@@ -39,7 +39,7 @@
display: none;
hr {
- margin: $gl-padding * 0.5 0;
+ margin: $gl-padding 0;
}
.btn-link {
@@ -71,9 +71,6 @@
.feature-highlight-popover {
width: 240px;
- padding: 0;
- border: 1px solid $border-color;
- box-shadow: 0 2px 4px $dropdown-shadow-color;
&.right > .arrow {
border-right-color: $border-color;
@@ -85,7 +82,7 @@
}
.feature-highlight-popover-sub-content {
- padding: 9px 14px;
+ padding: $gl-padding $gl-padding-12;
}
@include keyframes(pulse-highlight) {
diff --git a/app/assets/stylesheets/framework/issue_box.scss b/app/assets/stylesheets/framework/issue_box.scss
index e51f230a680..1a38f3ccce4 100644
--- a/app/assets/stylesheets/framework/issue_box.scss
+++ b/app/assets/stylesheets/framework/issue_box.scss
@@ -16,10 +16,10 @@
margin-top: 5px;
}
- border-radius: 3px;
+ border-radius: $border-radius-default;
display: block;
float: left;
- margin-right: 10px;
+ margin-right: $gl-padding-8;
color: $white-light;
font-size: $gl-font-size;
line-height: $gl-line-height-24;
diff --git a/app/assets/stylesheets/framework/mixins.scss b/app/assets/stylesheets/framework/mixins.scss
index e7278554e6e..ad5096761cd 100644
--- a/app/assets/stylesheets/framework/mixins.scss
+++ b/app/assets/stylesheets/framework/mixins.scss
@@ -396,3 +396,14 @@
width: $gl-font-size * $code-line-height * 0.9;
height: $gl-font-size * $code-line-height * 0.9;
}
+
+@mixin avatar-counter($border-radius: 1em) {
+ background-color: $gray-darkest;
+ color: $white-light;
+ border: 1px solid $gray-normal;
+ border-radius: $border-radius;
+ font-family: $regular-font;
+ font-size: 9px;
+ line-height: 16px;
+ text-align: center;
+}
diff --git a/app/assets/stylesheets/framework/typography.scss b/app/assets/stylesheets/framework/typography.scss
index 7c152efd9c7..9e1431963d9 100644
--- a/app/assets/stylesheets/framework/typography.scss
+++ b/app/assets/stylesheets/framework/typography.scss
@@ -403,6 +403,7 @@ code {
.git-revision-dropdown .dropdown-content ul li a {
@extend .ref-name;
+ word-break: break-all;
}
/**
diff --git a/app/assets/stylesheets/framework/variables.scss b/app/assets/stylesheets/framework/variables.scss
index dc451a97e17..07fc655307e 100644
--- a/app/assets/stylesheets/framework/variables.scss
+++ b/app/assets/stylesheets/framework/variables.scss
@@ -336,6 +336,7 @@ $tooltip-font-size: 12px;
*/
$gl-padding-4: 4px;
$gl-padding-8: 8px;
+$gl-padding-12: 12px;
$gl-padding: 16px;
$gl-padding-24: 24px;
$gl-padding-32: 32px;
@@ -810,6 +811,11 @@ $modal-border-color: #e9ecef;
$priority-label-empty-state-width: 114px;
/*
+Popovers
+*/
+$popover-max-width: 384px;
+
+/*
Issues Analytics
*/
$issues-analytics-popover-boarder-color: rgba(0, 0, 0, 0.15);
diff --git a/app/assets/stylesheets/page_bundles/ide.scss b/app/assets/stylesheets/page_bundles/ide.scss
index f08fa80495d..cbcd8a474f1 100644
--- a/app/assets/stylesheets/page_bundles/ide.scss
+++ b/app/assets/stylesheets/page_bundles/ide.scss
@@ -396,10 +396,6 @@ $ide-commit-header-height: 48px;
font-size: inherit;
}
- > div + div {
- padding-left: $gl-padding;
- }
-
svg {
vertical-align: sub;
}
@@ -410,13 +406,14 @@ $ide-commit-header-height: 48px;
}
}
+.ide-status-list {
+ > div + div {
+ padding-left: $gl-padding;
+ }
+}
+
.ide-status-file {
text-align: right;
-
- .ide-status-branch + &,
- &:first-child {
- margin-left: auto;
- }
}
// Not great, but this is to deal with our current output
.multi-file-preview-holder {
diff --git a/app/assets/stylesheets/pages/commits.scss b/app/assets/stylesheets/pages/commits.scss
index 77a36e59b03..e12ea6fcb99 100644
--- a/app/assets/stylesheets/pages/commits.scss
+++ b/app/assets/stylesheets/pages/commits.scss
@@ -180,6 +180,14 @@
display: flex;
align-items: center;
}
+
+ .committer {
+ color: $gl-text-color-tertiary;
+
+ .commit-author-link {
+ color: $gl-text-color;
+ }
+ }
}
.commit-actions {
diff --git a/app/assets/stylesheets/pages/diff.scss b/app/assets/stylesheets/pages/diff.scss
index 3b0d740def3..4ebf1019456 100644
--- a/app/assets/stylesheets/pages/diff.scss
+++ b/app/assets/stylesheets/pages/diff.scss
@@ -676,7 +676,7 @@ table.code {
.diff-comments-more-count,
.diff-notes-collapse {
- @extend .avatar-counter;
+ @include avatar-counter(50%);
}
.diff-notes-collapse {
diff --git a/app/assets/stylesheets/pages/issuable.scss b/app/assets/stylesheets/pages/issuable.scss
index 79282f9043c..dcbb23684d1 100644
--- a/app/assets/stylesheets/pages/issuable.scss
+++ b/app/assets/stylesheets/pages/issuable.scss
@@ -682,8 +682,7 @@
justify-content: center;
align-items: center;
margin-top: 0;
- padding-left: 9px;
- padding-right: 9px;
+ padding: 0 $gl-padding-8;
@include media-breakpoint-up(sm) {
display: inline-block;
diff --git a/app/assets/stylesheets/pages/milestone.scss b/app/assets/stylesheets/pages/milestone.scss
index 49608a3964f..00d84df1650 100644
--- a/app/assets/stylesheets/pages/milestone.scss
+++ b/app/assets/stylesheets/pages/milestone.scss
@@ -230,27 +230,6 @@ $status-box-line-height: 26px;
background-color: $white-light;
}
-.milestone-deprecation-message {
- .popover {
- padding: 0;
- }
-
- .popover-body,
- .popover-content {
- padding: 0;
- }
-}
-
-.milestone-popover-body {
- padding: $gl-padding-8;
- background-color: $gray-light;
-}
-
-.milestone-popover-footer {
- padding: $gl-padding-8 $gl-padding;
- border-top: 1px solid $white-dark;
-}
-
.milestone-popover-instructions-list {
padding-left: 2em;
diff --git a/app/assets/stylesheets/pages/notes.scss b/app/assets/stylesheets/pages/notes.scss
index 69dd583bc5b..5cacd42bf0d 100644
--- a/app/assets/stylesheets/pages/notes.scss
+++ b/app/assets/stylesheets/pages/notes.scss
@@ -431,7 +431,7 @@ $note-form-margin-left: 72px;
.notes > .note-discussion li.note.system-note {
border-bottom: 0;
- padding: 0 $gl-padding;
+ padding: 0;
}
}
diff --git a/app/assets/stylesheets/pages/prometheus.scss b/app/assets/stylesheets/pages/prometheus.scss
index c03554b287f..2d600e3aef6 100644
--- a/app/assets/stylesheets/pages/prometheus.scss
+++ b/app/assets/stylesheets/pages/prometheus.scss
@@ -136,7 +136,6 @@
> .popover-header,
> .popover-body {
padding: 8px;
- font-size: 12px;
white-space: nowrap;
position: relative;
}
diff --git a/app/controllers/admin/application_settings_controller.rb b/app/controllers/admin/application_settings_controller.rb
index d5bc723aa8c..57b976b9121 100644
--- a/app/controllers/admin/application_settings_controller.rb
+++ b/app/controllers/admin/application_settings_controller.rb
@@ -2,7 +2,9 @@
class Admin::ApplicationSettingsController < Admin::ApplicationController
include InternalRedirect
+
before_action :set_application_setting
+ before_action :whitelist_query_limiting, only: [:usage_data]
def show
end
@@ -102,6 +104,10 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController
@application_setting = Gitlab::CurrentSettings.current_application_settings
end
+ def whitelist_query_limiting
+ Gitlab::QueryLimiting.whitelist('https://gitlab.com/gitlab-org/gitlab-ce/issues/63107')
+ end
+
def application_setting_params
params[:application_setting] ||= {}
diff --git a/app/controllers/import/fogbugz_controller.rb b/app/controllers/import/fogbugz_controller.rb
index a37ba682b91..28ead8d44da 100644
--- a/app/controllers/import/fogbugz_controller.rb
+++ b/app/controllers/import/fogbugz_controller.rb
@@ -11,7 +11,7 @@ class Import::FogbugzController < Import::BaseController
def callback
begin
- res = Gitlab::FogbugzImport::Client.new(import_params.symbolize_keys)
+ res = Gitlab::FogbugzImport::Client.new(import_params.to_h.symbolize_keys)
rescue
# If the URI is invalid various errors can occur
return redirect_to new_import_fogbugz_path, alert: _('Could not connect to FogBugz, check your URL')
@@ -26,7 +26,7 @@ class Import::FogbugzController < Import::BaseController
end
def create_user_map
- user_map = params[:users]
+ user_map = user_map_params.to_h[:users]
unless user_map.is_a?(Hash) && user_map.all? { |k, v| !v[:name].blank? }
flash.now[:alert] = _('All users must have a name.')
@@ -99,6 +99,10 @@ class Import::FogbugzController < Import::BaseController
params.permit(:uri, :email, :password)
end
+ def user_map_params
+ params.permit(users: %w(name email gitlab_user))
+ end
+
def verify_fogbugz_import_enabled
render_404 unless fogbugz_import_enabled?
end
diff --git a/app/controllers/profiles/emails_controller.rb b/app/controllers/profiles/emails_controller.rb
index 503eda250b4..f666a1150a6 100644
--- a/app/controllers/profiles/emails_controller.rb
+++ b/app/controllers/profiles/emails_controller.rb
@@ -28,9 +28,9 @@ class Profiles::EmailsController < Profiles::ApplicationController
def resend_confirmation_instructions
if Emails::ConfirmService.new(current_user, user: current_user).execute(@email)
- flash[:notice] = "Confirmation email sent to #{@email.email}"
+ flash[:notice] = _("Confirmation email sent to %{email}") % { email: @email.email }
else
- flash[:alert] = "There was a problem sending the confirmation email"
+ flash[:alert] = _("There was a problem sending the confirmation email")
end
redirect_to profile_emails_url
diff --git a/app/controllers/projects/environments/prometheus_api_controller.rb b/app/controllers/projects/environments/prometheus_api_controller.rb
index f8ef23cd83e..9c6c6513a78 100644
--- a/app/controllers/projects/environments/prometheus_api_controller.rb
+++ b/app/controllers/projects/environments/prometheus_api_controller.rb
@@ -13,7 +13,7 @@ class Projects::Environments::PrometheusApiController < Projects::ApplicationCon
).execute
if result.nil?
- return render status: :accepted, json: {
+ return render status: :no_content, json: {
status: _('processing'),
message: _('Not ready yet. Try again later.')
}
diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb
index 135117926be..9e7e3ed5afb 100644
--- a/app/controllers/projects/merge_requests_controller.rb
+++ b/app/controllers/projects/merge_requests_controller.rb
@@ -33,7 +33,7 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
def show
close_merge_request_if_no_source_project
- @merge_request.check_mergeability
+ mark_merge_request_mergeable
respond_to do |format|
format.html do
@@ -251,6 +251,10 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
@merge_request.has_no_commits? && !@merge_request.target_branch_exists?
end
+ def mark_merge_request_mergeable
+ @merge_request.check_if_can_be_merged
+ end
+
def merge!
# Disable the CI check if auto_merge_strategy is specified since we have
# to wait until CI completes to know
@@ -269,9 +273,15 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
@merge_request.update(merge_error: nil, squash: merge_params.fetch(:squash, false))
if auto_merge_requested?
- AutoMergeService.new(project, current_user, merge_params)
- .execute(merge_request,
- params[:auto_merge_strategy] || AutoMergeService::STRATEGY_MERGE_WHEN_PIPELINE_SUCCEEDS)
+ if merge_request.auto_merge_enabled?
+ # TODO: We should have a dedicated endpoint for updating merge params.
+ # See https://gitlab.com/gitlab-org/gitlab-ce/issues/63130.
+ AutoMergeService.new(project, current_user, merge_params).update(merge_request)
+ else
+ AutoMergeService.new(project, current_user, merge_params)
+ .execute(merge_request,
+ params[:auto_merge_strategy] || AutoMergeService::STRATEGY_MERGE_WHEN_PIPELINE_SUCCEEDS)
+ end
else
@merge_request.merge_async(current_user.id, merge_params)
diff --git a/app/finders/issuable_finder.rb b/app/finders/issuable_finder.rb
index 50e9418677c..3592505a977 100644
--- a/app/finders/issuable_finder.rb
+++ b/app/finders/issuable_finder.rb
@@ -43,7 +43,7 @@ class IssuableFinder
FILTER_NONE = 'none'.freeze
FILTER_ANY = 'any'.freeze
- # This is accepted as a deprecated filter and is also used in unassigning users
+ # This is used in unassigning users
NONE = '0'.freeze
attr_accessor :current_user, :params
@@ -248,8 +248,7 @@ class IssuableFinder
def filter_by_no_label?
downcased = label_names.map(&:downcase)
- # Label::NONE is deprecated and should be removed in 12.0
- downcased.include?(FILTER_NONE) || downcased.include?(Label::NONE)
+ downcased.include?(FILTER_NONE)
end
def filter_by_any_label?
@@ -449,8 +448,7 @@ class IssuableFinder
# rubocop: enable CodeReuse/ActiveRecord
def filter_by_no_assignee?
- # Assignee_id takes precedence over assignee_username
- [NONE, FILTER_NONE].include?(params[:assignee_id].to_s.downcase) || params[:assignee_username].to_s == NONE
+ params[:assignee_id].to_s.downcase == FILTER_NONE
end
def filter_by_any_assignee?
diff --git a/app/graphql/types/tree/blob_type.rb b/app/graphql/types/tree/blob_type.rb
index f2b7d5df2b2..760781f3612 100644
--- a/app/graphql/types/tree/blob_type.rb
+++ b/app/graphql/types/tree/blob_type.rb
@@ -9,6 +9,9 @@ module Types
graphql_name 'Blob'
field :web_url, GraphQL::STRING_TYPE, null: true
+ field :lfs_oid, GraphQL::STRING_TYPE, null: true, resolve: -> (blob, args, ctx) do
+ Gitlab::Graphql::Loaders::BatchLfsOidLoader.new(blob.repository, blob.id).find
+ end
end
end
end
diff --git a/app/helpers/environments_helper.rb b/app/helpers/environments_helper.rb
index 8002eb08ada..855b243cc8a 100644
--- a/app/helpers/environments_helper.rb
+++ b/app/helpers/environments_helper.rb
@@ -26,6 +26,7 @@ module EnvironmentsHelper
"empty-no-data-svg-path" => image_path('illustrations/monitoring/no_data.svg'),
"empty-unable-to-connect-svg-path" => image_path('illustrations/monitoring/unable_to_connect.svg'),
"metrics-endpoint" => additional_metrics_project_environment_path(project, environment, format: :json),
+ "dashboard-endpoint" => metrics_dashboard_project_environment_path(project, environment, format: :json),
"deployment-endpoint" => project_environment_deployments_path(project, environment, format: :json),
"environments-endpoint": project_environments_path(project, format: :json),
"project-path" => project_path(project),
diff --git a/app/models/broadcast_message.rb b/app/models/broadcast_message.rb
index 18fe2a9624f..0fd8dca70b4 100644
--- a/app/models/broadcast_message.rb
+++ b/app/models/broadcast_message.rb
@@ -17,13 +17,11 @@ class BroadcastMessage < ApplicationRecord
default_value_for :font, '#FFFFFF'
CACHE_KEY = 'broadcast_message_current_json'.freeze
- LEGACY_CACHE_KEY = 'broadcast_message_current'.freeze
after_commit :flush_redis_cache
def self.current
messages = cache.fetch(CACHE_KEY, as: BroadcastMessage, expires_in: cache_expires_in) do
- remove_legacy_cache_key
current_and_future_messages
end
@@ -50,14 +48,6 @@ class BroadcastMessage < ApplicationRecord
nil
end
- # This can be removed in GitLab 12.0+
- # The old cache key had an indefinite lifetime, and in an HA
- # environment a one-shot migration would not work because the cache
- # would be repopulated by a node that has not been upgraded.
- def self.remove_legacy_cache_key
- cache.expire(LEGACY_CACHE_KEY)
- end
-
def active?
started? && !ended?
end
@@ -84,6 +74,5 @@ class BroadcastMessage < ApplicationRecord
def flush_redis_cache
self.class.cache.expire(CACHE_KEY)
- self.class.remove_legacy_cache_key
end
end
diff --git a/app/models/ci/pipeline_schedule.rb b/app/models/ci/pipeline_schedule.rb
index c40ad39be61..6a4241c94bc 100644
--- a/app/models/ci/pipeline_schedule.rb
+++ b/app/models/ci/pipeline_schedule.rb
@@ -73,7 +73,8 @@ module Ci
private
def ideal_next_run_at
- Gitlab::Ci::CronParser.new(cron, cron_timezone).next_time_from(Time.now)
+ Gitlab::Ci::CronParser.new(cron, cron_timezone)
+ .next_time_from(Time.zone.now)
end
end
end
diff --git a/app/models/clusters/cluster.rb b/app/models/clusters/cluster.rb
index e1d6b2a802b..ccc877fb924 100644
--- a/app/models/clusters/cluster.rb
+++ b/app/models/clusters/cluster.rb
@@ -8,7 +8,6 @@ module Clusters
include ReactiveCaching
self.table_name = 'clusters'
- self.reactive_cache_key = -> (cluster) { [cluster.class.model_name.singular, cluster.id] }
PROJECT_ONLY_APPLICATIONS = {
Applications::Jupyter.application_name => Applications::Jupyter,
diff --git a/app/models/clusters/platforms/kubernetes.rb b/app/models/clusters/platforms/kubernetes.rb
index 9b951578aee..8e06156c73d 100644
--- a/app/models/clusters/platforms/kubernetes.rb
+++ b/app/models/clusters/platforms/kubernetes.rb
@@ -11,7 +11,6 @@ module Clusters
RESERVED_NAMESPACES = %w(gitlab-managed-apps).freeze
self.table_name = 'cluster_platforms_kubernetes'
- self.reactive_cache_key = ->(kubernetes) { [kubernetes.class.model_name.singular, kubernetes.id] }
belongs_to :cluster, inverse_of: :platform_kubernetes, class_name: 'Clusters::Cluster'
diff --git a/app/models/concerns/prometheus_adapter.rb b/app/models/concerns/prometheus_adapter.rb
index 258c819f243..c2542dbe743 100644
--- a/app/models/concerns/prometheus_adapter.rb
+++ b/app/models/concerns/prometheus_adapter.rb
@@ -6,7 +6,6 @@ module PrometheusAdapter
included do
include ReactiveCaching
- self.reactive_cache_key = ->(adapter) { [adapter.class.model_name.singular, adapter.id] }
self.reactive_cache_lease_timeout = 30.seconds
self.reactive_cache_refresh_interval = 30.seconds
self.reactive_cache_lifetime = 1.minute
diff --git a/app/models/concerns/reactive_caching.rb b/app/models/concerns/reactive_caching.rb
index 1e09cd89550..6c3962b4c4f 100644
--- a/app/models/concerns/reactive_caching.rb
+++ b/app/models/concerns/reactive_caching.rb
@@ -10,8 +10,6 @@
# class Foo < ApplicationRecord
# include ReactiveCaching
#
-# self.reactive_cache_key = ->(thing) { ["foo", thing.id] }
-#
# after_save :clear_reactive_cache!
#
# def calculate_reactive_cache
@@ -89,6 +87,8 @@ module ReactiveCaching
class_attribute :reactive_cache_worker_finder
# defaults
+ self.reactive_cache_key = -> (record) { [model_name.singular, record.id] }
+
self.reactive_cache_lease_timeout = 2.minutes
self.reactive_cache_refresh_interval = 1.minute
diff --git a/app/models/label.rb b/app/models/label.rb
index e9085e8bd25..b83e0862bab 100644
--- a/app/models/label.rb
+++ b/app/models/label.rb
@@ -13,7 +13,6 @@ class Label < ApplicationRecord
cache_markdown_field :description, pipeline: :single_line
DEFAULT_COLOR = '#428BCA'
- NONE = 'no label'
default_value_for :color, DEFAULT_COLOR
diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb
index 4fcaac75655..7481f1939ad 100644
--- a/app/models/merge_request.rb
+++ b/app/models/merge_request.rb
@@ -725,16 +725,19 @@ class MergeRequest < ApplicationRecord
MergeRequests::ReloadDiffsService.new(self, current_user).execute
end
-
- def check_mergeability
- MergeRequests::MergeabilityCheckService.new(self).execute
- end
# rubocop: enable CodeReuse/ServiceClass
- # Returns boolean indicating the merge_status should be rechecked in order to
- # switch to either can_be_merged or cannot_be_merged.
- def recheck_merge_status?
- self.class.state_machines[:merge_status].check_state?(merge_status)
+ def check_if_can_be_merged
+ return unless self.class.state_machines[:merge_status].check_state?(merge_status) && Gitlab::Database.read_write?
+
+ can_be_merged =
+ !broken? && project.repository.can_be_merged?(diff_head_sha, target_branch)
+
+ if can_be_merged
+ mark_as_mergeable
+ else
+ mark_as_unmergeable
+ end
end
def merge_event
@@ -760,7 +763,7 @@ class MergeRequest < ApplicationRecord
def mergeable?(skip_ci_check: false)
return false unless mergeable_state?(skip_ci_check: skip_ci_check)
- check_mergeability
+ check_if_can_be_merged
can_be_merged? && !should_be_rebased?
end
@@ -775,6 +778,15 @@ class MergeRequest < ApplicationRecord
true
end
+ def mergeable_to_ref?
+ return false unless mergeable_state?(skip_ci_check: true, skip_discussions_check: true)
+
+ # Given the `merge_ref_path` will have the same
+ # state the `target_branch` would have. Ideally
+ # we need to check if it can be merged to it.
+ project.repository.can_be_merged?(diff_head_sha, target_branch)
+ end
+
def ff_merge_possible?
project.repository.ancestor?(target_branch_sha, diff_head_sha)
end
@@ -1087,12 +1099,6 @@ class MergeRequest < ApplicationRecord
target_project.repository.fetch_source_branch!(source_project.repository, source_branch, ref_path)
end
- # Returns the current merge-ref HEAD commit.
- #
- def merge_ref_head
- project.repository.commit(merge_ref_path)
- end
-
def ref_path
"refs/#{Repository::REF_MERGE_REQUEST}/#{iid}/head"
end
diff --git a/app/models/notification_recipient.rb b/app/models/notification_recipient.rb
index 9b2bbb7eba5..a7f73c0f29c 100644
--- a/app/models/notification_recipient.rb
+++ b/app/models/notification_recipient.rb
@@ -101,6 +101,7 @@ class NotificationRecipient
end
def excluded_watcher_action?
+ return false unless @type == :watch
return false unless @custom_action
NotificationSetting::EXCLUDED_WATCHER_EVENTS.include?(@custom_action)
@@ -140,7 +141,7 @@ class NotificationRecipient
return project_setting unless project_setting.nil? || project_setting.global?
- group_setting = closest_non_global_group_notification_settting
+ group_setting = closest_non_global_group_notification_setting
return group_setting unless group_setting.nil?
@@ -148,7 +149,7 @@ class NotificationRecipient
end
# Returns the notification_setting of the lowest group in hierarchy with non global level
- def closest_non_global_group_notification_settting
+ def closest_non_global_group_notification_setting
return unless @group
@group
diff --git a/app/models/project.rb b/app/models/project.rb
index e64a4b313aa..9d17d68eee2 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -311,7 +311,7 @@ class Project < ApplicationRecord
delegate :root_ancestor, to: :namespace, allow_nil: true
delegate :last_pipeline, to: :commit, allow_nil: true
delegate :external_dashboard_url, to: :metrics_setting, allow_nil: true, prefix: true
- delegate :default_git_depth, :default_git_depth=, to: :ci_cd_settings
+ delegate :default_git_depth, :default_git_depth=, to: :ci_cd_settings, prefix: :ci
# Validations
validates :creator, presence: true, on: :create
diff --git a/app/models/project_ci_cd_setting.rb b/app/models/project_ci_cd_setting.rb
index 492d50766ea..821e022f51b 100644
--- a/app/models/project_ci_cd_setting.rb
+++ b/app/models/project_ci_cd_setting.rb
@@ -31,6 +31,8 @@ class ProjectCiCdSetting < ApplicationRecord
private
def set_default_git_depth
+ return unless Feature.enabled?(:ci_set_project_default_git_depth, default_enabled: true)
+
self.default_git_depth ||= DEFAULT_GIT_DEPTH
end
end
diff --git a/app/models/project_statistics.rb b/app/models/project_statistics.rb
index 11e3737298c..8a179b4d56d 100644
--- a/app/models/project_statistics.rb
+++ b/app/models/project_statistics.rb
@@ -54,7 +54,7 @@ class ProjectStatistics < ApplicationRecord
end
def update_storage_size
- self.storage_size = repository_size + wiki_size + lfs_objects_size + build_artifacts_size + packages_size
+ self.storage_size = repository_size + wiki_size.to_i + lfs_objects_size + build_artifacts_size + packages_size
end
# Since this incremental update method does not call update_storage_size above,
diff --git a/app/policies/project_policy.rb b/app/policies/project_policy.rb
index 3218c04b219..728a3040227 100644
--- a/app/policies/project_policy.rb
+++ b/app/policies/project_policy.rb
@@ -164,6 +164,7 @@ class ProjectPolicy < BasePolicy
enable :set_issue_iid
enable :set_issue_created_at
+ enable :set_issue_updated_at
enable :set_note_created_at
end
diff --git a/app/presenters/blob_presenter.rb b/app/presenters/blob_presenter.rb
index c5675ef3ea3..91c9abe750b 100644
--- a/app/presenters/blob_presenter.rb
+++ b/app/presenters/blob_presenter.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-class BlobPresenter < Gitlab::View::Presenter::Simple
+class BlobPresenter < Gitlab::View::Presenter::Delegated
presents :blob
def highlight(plain: nil)
diff --git a/app/presenters/ci/build_runner_presenter.rb b/app/presenters/ci/build_runner_presenter.rb
index 471b6d3b726..b928988ed8c 100644
--- a/app/presenters/ci/build_runner_presenter.rb
+++ b/app/presenters/ci/build_runner_presenter.rb
@@ -27,8 +27,8 @@ module Ci
def git_depth
if git_depth_variable
git_depth_variable[:value]
- else
- project.default_git_depth
+ elsif Feature.enabled?(:ci_project_git_depth, default_enabled: true)
+ project.ci_default_git_depth
end.to_i
end
diff --git a/app/services/auto_merge/base_service.rb b/app/services/auto_merge/base_service.rb
index 058105db3a4..d726085b89a 100644
--- a/app/services/auto_merge/base_service.rb
+++ b/app/services/auto_merge/base_service.rb
@@ -14,6 +14,17 @@ module AutoMerge
yield if block_given?
+ # Notify the event that auto merge is enabled or merge param is updated
+ AutoMergeProcessWorker.perform_async(merge_request.id)
+
+ strategy.to_sym
+ end
+
+ def update(merge_request)
+ merge_request.merge_params.merge!(params)
+
+ return :failed unless merge_request.save
+
strategy.to_sym
end
diff --git a/app/services/auto_merge_service.rb b/app/services/auto_merge_service.rb
index a3a780ff388..926d2f5fc66 100644
--- a/app/services/auto_merge_service.rb
+++ b/app/services/auto_merge_service.rb
@@ -24,6 +24,12 @@ class AutoMergeService < BaseService
service.execute(merge_request)
end
+ def update(merge_request)
+ return :failed unless merge_request.auto_merge_enabled?
+
+ get_service_instance(merge_request.auto_merge_strategy).update(merge_request)
+ end
+
def process(merge_request)
return unless merge_request.auto_merge_enabled?
diff --git a/app/services/ci/pipeline_schedule_service.rb b/app/services/ci/pipeline_schedule_service.rb
index 387d0351490..5b5e9a26520 100644
--- a/app/services/ci/pipeline_schedule_service.rb
+++ b/app/services/ci/pipeline_schedule_service.rb
@@ -7,7 +7,7 @@ module Ci
# Otherwise, multiple pipelines could be created in a short interval.
schedule.schedule_next_run!
- RunPipelineScheduleWorker.perform_async(schedule.id, schedule.owner.id)
+ RunPipelineScheduleWorker.perform_async(schedule.id, schedule.owner&.id)
end
end
end
diff --git a/app/services/merge_requests/base_service.rb b/app/services/merge_requests/base_service.rb
index 2cfed62ce49..c34fbeb2adb 100644
--- a/app/services/merge_requests/base_service.rb
+++ b/app/services/merge_requests/base_service.rb
@@ -68,6 +68,10 @@ module MergeRequests
!merge_request.for_fork?
end
+ def cancel_auto_merge(merge_request)
+ AutoMergeService.new(project, current_user).cancel(merge_request)
+ end
+
# Returns all origin and fork merge requests from `@project` satisfying passed arguments.
# rubocop: disable CodeReuse/ActiveRecord
def merge_requests_for(source_branch, mr_states: [:opened])
diff --git a/app/services/merge_requests/close_service.rb b/app/services/merge_requests/close_service.rb
index b0f6166ea1c..b81a4dd81d2 100644
--- a/app/services/merge_requests/close_service.rb
+++ b/app/services/merge_requests/close_service.rb
@@ -34,9 +34,5 @@ module MergeRequests
merge_request_metrics_service(merge_request).close(close_event)
end
end
-
- def cancel_auto_merge(merge_request)
- AutoMergeService.new(project, current_user).cancel(merge_request)
- end
end
end
diff --git a/app/services/merge_requests/merge_to_ref_service.rb b/app/services/merge_requests/merge_to_ref_service.rb
index 8670b9ccf3d..87147d90c32 100644
--- a/app/services/merge_requests/merge_to_ref_service.rb
+++ b/app/services/merge_requests/merge_to_ref_service.rb
@@ -20,14 +20,20 @@ module MergeRequests
raise_error('Conflicts detected during merge') unless commit_id
- success(commit_id: commit_id)
- rescue MergeError, ArgumentError => error
+ commit = project.commit(commit_id)
+ target_id, source_id = commit.parent_ids
+
+ success(commit_id: commit.id,
+ target_id: target_id,
+ source_id: source_id)
+ rescue MergeError => error
error(error.message)
end
private
def validate!
+ authorization_check!
error_check!
end
@@ -37,13 +43,21 @@ module MergeRequests
error =
if !hooks_validation_pass?(merge_request)
hooks_validation_error(merge_request)
- elsif source.blank?
+ elsif !@merge_request.mergeable_to_ref?
+ "Merge request is not mergeable to #{target_ref}"
+ elsif !source
'No source for merge'
end
raise_error(error) if error
end
+ def authorization_check!
+ unless Ability.allowed?(current_user, :admin_merge_request, project)
+ raise_error("You are not allowed to merge to this ref")
+ end
+ end
+
def target_ref
merge_request.merge_ref_path
end
diff --git a/app/services/merge_requests/mergeability_check_service.rb b/app/services/merge_requests/mergeability_check_service.rb
deleted file mode 100644
index ef833774e65..00000000000
--- a/app/services/merge_requests/mergeability_check_service.rb
+++ /dev/null
@@ -1,82 +0,0 @@
-# frozen_string_literal: true
-
-module MergeRequests
- class MergeabilityCheckService < ::BaseService
- include Gitlab::Utils::StrongMemoize
-
- delegate :project, to: :@merge_request
- delegate :repository, to: :project
-
- def initialize(merge_request)
- @merge_request = merge_request
- end
-
- # Updates the MR merge_status. Whenever it switches to a can_be_merged state,
- # the merge-ref is refreshed.
- #
- # Returns a ServiceResponse indicating merge_status is/became can_be_merged
- # and the merge-ref is synced. Success in case of being/becoming mergeable,
- # error otherwise.
- def execute
- return ServiceResponse.error(message: 'Invalid argument') unless merge_request
- return ServiceResponse.error(message: 'Unsupported operation') if Gitlab::Database.read_only?
-
- update_merge_status
-
- unless merge_request.can_be_merged?
- return ServiceResponse.error(message: 'Merge request is not mergeable')
- end
-
- unless payload.fetch(:merge_ref_head)
- return ServiceResponse.error(message: 'Merge ref was not found')
- end
-
- ServiceResponse.success(payload: payload)
- end
-
- private
-
- attr_reader :merge_request
-
- def payload
- strong_memoize(:payload) do
- {
- merge_ref_head: merge_ref_head_payload
- }
- end
- end
-
- def merge_ref_head_payload
- commit = merge_request.merge_ref_head
-
- return unless commit
-
- target_id, source_id = commit.parent_ids
-
- {
- commit_id: commit.id,
- source_id: source_id,
- target_id: target_id
- }
- end
-
- def update_merge_status
- return unless merge_request.recheck_merge_status?
-
- if can_git_merge?
- merge_to_ref && merge_request.mark_as_mergeable
- else
- merge_request.mark_as_unmergeable
- end
- end
-
- def can_git_merge?
- !merge_request.broken? && repository.can_be_merged?(merge_request.diff_head_sha, merge_request.target_branch)
- end
-
- def merge_to_ref
- result = MergeRequests::MergeToRefService.new(project, merge_request.author).execute(merge_request)
- result[:status] == :success
- end
- end
-end
diff --git a/app/services/merge_requests/refresh_service.rb b/app/services/merge_requests/refresh_service.rb
index 08130a531ee..4b199bd8fa8 100644
--- a/app/services/merge_requests/refresh_service.rb
+++ b/app/services/merge_requests/refresh_service.rb
@@ -24,7 +24,7 @@ module MergeRequests
reload_merge_requests
outdate_suggestions
refresh_pipelines_on_merge_requests
- cancel_auto_merge
+ cancel_auto_merges
mark_pending_todos_done
cache_merge_requests_closing_issues
@@ -142,9 +142,9 @@ module MergeRequests
end
end
- def cancel_auto_merge
+ def cancel_auto_merges
merge_requests_for_source_branch.each do |merge_request|
- AutoMergeService.new(project, current_user).cancel(merge_request)
+ cancel_auto_merge(merge_request)
end
end
diff --git a/app/services/merge_requests/update_service.rb b/app/services/merge_requests/update_service.rb
index 6a0f3000ffb..0066cd0491f 100644
--- a/app/services/merge_requests/update_service.rb
+++ b/app/services/merge_requests/update_service.rb
@@ -43,6 +43,8 @@ module MergeRequests
create_branch_change_note(merge_request, 'target',
merge_request.previous_changes['target_branch'].first,
merge_request.target_branch)
+
+ cancel_auto_merge(merge_request)
end
if merge_request.assignees != old_assignees
diff --git a/app/services/projects/fork_service.rb b/app/services/projects/fork_service.rb
index 0b4ab7b8e4d..d8fa9d37359 100644
--- a/app/services/projects/fork_service.rb
+++ b/app/services/projects/fork_service.rb
@@ -43,10 +43,10 @@ module Projects
shared_runners_enabled: @project.shared_runners_enabled,
namespace_id: target_namespace.id,
fork_network: fork_network,
- # We need to set default_git_depth to 0 for the forked project when
- # @project.default_git_depth is nil in order to keep the same behaviour
+ # We need to set ci_default_git_depth to 0 for the forked project when
+ # @project.ci_default_git_depth is nil in order to keep the same behaviour
# and not get ProjectCiCdSetting::DEFAULT_GIT_DEPTH set on create
- ci_cd_settings_attributes: { default_git_depth: @project.default_git_depth || 0 },
+ ci_cd_settings_attributes: { default_git_depth: @project.ci_default_git_depth || 0 },
# We need to assign the fork network membership after the project has
# been instantiated to avoid ActiveRecord trying to create it when
# initializing the project, as that would cause a foreign key constraint
diff --git a/app/services/service_response.rb b/app/services/service_response.rb
index f3437ba16de..1de30e68d87 100644
--- a/app/services/service_response.rb
+++ b/app/services/service_response.rb
@@ -1,20 +1,19 @@
# frozen_string_literal: true
class ServiceResponse
- def self.success(message: nil, payload: {})
- new(status: :success, message: message, payload: payload)
+ def self.success(message: nil)
+ new(status: :success, message: message)
end
- def self.error(message:, payload: {}, http_status: nil)
- new(status: :error, message: message, payload: payload, http_status: http_status)
+ def self.error(message:, http_status: nil)
+ new(status: :error, message: message, http_status: http_status)
end
- attr_reader :status, :message, :http_status, :payload
+ attr_reader :status, :message, :http_status
- def initialize(status:, message: nil, payload: {}, http_status: nil)
+ def initialize(status:, message: nil, http_status: nil)
self.status = status
self.message = message
- self.payload = payload
self.http_status = http_status
end
@@ -28,5 +27,5 @@ class ServiceResponse
private
- attr_writer :status, :message, :http_status, :payload
+ attr_writer :status, :message, :http_status
end
diff --git a/app/views/admin/application_settings/_performance_bar.html.haml b/app/views/admin/application_settings/_performance_bar.html.haml
index f992d531ea5..1e66b635038 100644
--- a/app/views/admin/application_settings/_performance_bar.html.haml
+++ b/app/views/admin/application_settings/_performance_bar.html.haml
@@ -6,7 +6,7 @@
.form-check
= f.check_box :performance_bar_enabled, class: 'form-check-input'
= f.label :performance_bar_enabled, class: 'form-check-label qa-enable-performance-bar-checkbox' do
- Enable the Performance Bar
+ Enable access to the Performance Bar
.form-group
= f.label :performance_bar_allowed_group_path, 'Allowed group', class: 'label-bold'
= f.text_field :performance_bar_allowed_group_path, class: 'form-control', placeholder: 'my-org/my-group', value: @application_setting.performance_bar_allowed_group&.full_path
diff --git a/app/views/admin/application_settings/_visibility_and_access.html.haml b/app/views/admin/application_settings/_visibility_and_access.html.haml
index 03ef2924617..c07bafbe302 100644
--- a/app/views/admin/application_settings/_visibility_and_access.html.haml
+++ b/app/views/admin/application_settings/_visibility_and_access.html.haml
@@ -8,6 +8,7 @@
.form-group
= f.label s_('ProjectCreationLevel|Default project creation protection'), class: 'label-bold'
= f.select :default_project_creation, options_for_select(Gitlab::Access.project_creation_options, @application_setting.default_project_creation), {}, class: 'form-control'
+ = render_if_exists 'admin/application_settings/default_project_deletion_protection_setting', form: f
.form-group.visibility-level-setting
= f.label :default_project_visibility, class: 'label-bold'
= render('shared/visibility_radios', model_method: :default_project_visibility, form: f, selected_level: @application_setting.default_project_visibility, form_model: Project.new)
diff --git a/app/views/admin/application_settings/metrics_and_profiling.html.haml b/app/views/admin/application_settings/metrics_and_profiling.html.haml
index d5ba6abe7af..01d61beaf53 100644
--- a/app/views/admin/application_settings/metrics_and_profiling.html.haml
+++ b/app/views/admin/application_settings/metrics_and_profiling.html.haml
@@ -31,7 +31,7 @@
%button.btn.btn-default.js-settings-toggle{ type: 'button' }
= expanded_by_default? ? _('Collapse') : _('Expand')
%p
- = _('Enable the Performance Bar for a given group.')
+ = _('Enable access to the Performance Bar for a given group.')
= link_to icon('question-circle'), help_page_path('administration/monitoring/performance/performance_bar')
.settings-content
= render 'performance_bar'
diff --git a/app/views/layouts/nav/sidebar/_project.html.haml b/app/views/layouts/nav/sidebar/_project.html.haml
index 399305baec1..9b6551552c7 100644
--- a/app/views/layouts/nav/sidebar/_project.html.haml
+++ b/app/views/layouts/nav/sidebar/_project.html.haml
@@ -36,6 +36,8 @@
= render_if_exists 'projects/sidebar/security_dashboard'
+ = render_if_exists 'projects/sidebar/dependencies'
+
- if can?(current_user, :read_cycle_analytics, @project)
= nav_link(path: 'cycle_analytics#show') do
= link_to project_cycle_analytics_path(@project), title: _('Cycle Analytics'), class: 'shortcuts-project-cycle-analytics' do
diff --git a/app/views/profiles/emails/index.html.haml b/app/views/profiles/emails/index.html.haml
index c90a0b3e329..3c20518c038 100644
--- a/app/views/profiles/emails/index.html.haml
+++ b/app/views/profiles/emails/index.html.haml
@@ -1,4 +1,4 @@
-- page_title "Emails"
+- page_title _('Emails')
- @content_class = "limit-container-width" unless fluid_layout
.row.prepend-top-default
@@ -6,58 +6,58 @@
%h4.prepend-top-0
= page_title
%p
- Control emails linked to your account
+ = _('Control emails linked to your account')
.col-lg-8
%h4.prepend-top-0
- Add email address
+ = _('Add email address')
= form_for 'email', url: profile_emails_path do |f|
.form-group
- = f.label :email, class: 'label-bold'
+ = f.label :email, _('Email'), class: 'label-bold'
= f.text_field :email, class: 'form-control'
.prepend-top-default
- = f.submit 'Add email address', class: 'btn btn-success'
+ = f.submit _('Add email address'), class: 'btn btn-success'
%hr
%h4.prepend-top-0
- Linked emails (#{@emails.count + 1})
+ = _('Linked emails (%{email_count})') % { email_count: @emails.count + 1 }
.account-well.append-bottom-default
%ul
%li
- Your Primary Email will be used for avatar detection.
+ = _('Your Primary Email will be used for avatar detection.')
%li
- Your Commit Email will be used for web based operations, such as edits and merges.
+ = _('Your Commit Email will be used for web based operations, such as edits and merges.')
%li
- Your Default Notification Email will be used for account notifications if a
- = link_to 'group-specific email address', profile_notifications_path
- is not set.
+ - address = profile_notifications_path
+ - notification_message = _('Your Default Notification Email will be used for account notifications if a %{openingTag}group-specific email address%{closingTag} is not set.') % { openingTag: "<a href='#{address}'>".html_safe, closingTag: '</a>'.html_safe}
+ = notification_message.html_safe
%li
- Your Public Email will be displayed on your public profile.
+ = _('Your Public Email will be displayed on your public profile.')
%li
- All email addresses will be used to identify your commits.
+ = _('All email addresses will be used to identify your commits.')
%ul.content-list
%li
= render partial: 'shared/email_with_badge', locals: { email: @primary_email, verified: current_user.confirmed? }
%span.float-right
- %span.badge.badge-success Primary email
+ %span.badge.badge-success= s_('Profiles|Primary email')
- if @primary_email === current_user.commit_email
- %span.badge.badge-info Commit email
+ %span.badge.badge-info= s_('Profiles|Commit email')
- if @primary_email === current_user.public_email
- %span.badge.badge-info Public email
+ %span.badge.badge-info= s_('Profiles|Public email')
- if @primary_email === current_user.notification_email
- %span.badge.badge-info Default notification email
+ %span.badge.badge-info= s_('Profiles|Default notification email')
- @emails.each do |email|
%li
= render partial: 'shared/email_with_badge', locals: { email: email.email, verified: email.confirmed? }
%span.float-right
- if email.email === current_user.commit_email
- %span.badge.badge-info Commit email
+ %span.badge.badge-info= s_('Profiles|Commit email')
- if email.email === current_user.public_email
- %span.badge.badge-info Public email
+ %span.badge.badge-info= s_('Profiles|Public email')
- if email.email === current_user.notification_email
- %span.badge.badge-info Notification email
+ %span.badge.badge-info= s_('Profiles|Notification email')
- unless email.confirmed?
- - confirm_title = "#{email.confirmation_sent_at ? 'Resend' : 'Send'} confirmation email"
+ - confirm_title = "#{email.confirmation_sent_at ? _('Resend confirmation email') : _('Send confirmation email')}"
= link_to confirm_title, resend_confirmation_instructions_profile_email_path(email), method: :put, class: 'btn btn-sm btn-warning prepend-left-10'
- = link_to profile_email_path(email), data: { confirm: 'Are you sure?'}, method: :delete, class: 'btn btn-sm btn-danger prepend-left-10' do
- %span.sr-only Remove
+ = link_to profile_email_path(email), data: { confirm: _('Are you sure?')}, method: :delete, class: 'btn btn-sm btn-danger prepend-left-10' do
+ %span.sr-only= _('Remove')
= icon('trash')
diff --git a/app/views/profiles/keys/_form.html.haml b/app/views/profiles/keys/_form.html.haml
index 7846cdbcd52..63ef5eaa172 100644
--- a/app/views/profiles/keys/_form.html.haml
+++ b/app/views/profiles/keys/_form.html.haml
@@ -4,8 +4,8 @@
.form-group
= f.label :key, s_('Profiles|Key'), class: 'label-bold'
- %p= _("Paste your public SSH key, which is usually contained in the file '~/.ssh/id_rsa.pub' and begins with 'ssh-rsa'. Don't use your private SSH key.")
- = f.text_area :key, class: "form-control js-add-ssh-key-validation-input qa-key-public-key-field", rows: 8, required: true, placeholder: s_('Profiles|Typically starts with "ssh-rsa …"')
+ %p= _("Paste your public SSH key, which is usually contained in the file '~/.ssh/id_ed25519.pub' or '~/.ssh/id_rsa.pub' and begins with 'ssh-ed25519' or 'ssh-rsa'. Don't use your private SSH key.")
+ = f.text_area :key, class: "form-control js-add-ssh-key-validation-input qa-key-public-key-field", rows: 8, required: true, placeholder: s_('Profiles|Typically starts with "ssh-ed25519 …" or "ssh-rsa …"')
.form-group
= f.label :title, _('Title'), class: 'label-bold'
= f.text_field :title, class: "form-control input-lg qa-key-title-field", required: true, placeholder: s_('Profiles|e.g. My MacBook key')
diff --git a/app/views/projects/branches/_branch.html.haml b/app/views/projects/branches/_branch.html.haml
index 1074cd6bf4e..a5eaae2dff4 100644
--- a/app/views/projects/branches/_branch.html.haml
+++ b/app/views/projects/branches/_branch.html.haml
@@ -22,7 +22,7 @@
%span.badge.badge-success.prepend-left-5
= s_('Branches|protected')
- = render_if_exists 'projects/branches/diverged_from_upstream'
+ = render_if_exists 'projects/branches/diverged_from_upstream', branch: branch
.block-truncated
- if commit
diff --git a/app/views/projects/commit/_commit_box.html.haml b/app/views/projects/commit/_commit_box.html.haml
index ef2777e6601..77ea2c04b28 100644
--- a/app/views/projects/commit/_commit_box.html.haml
+++ b/app/views/projects/commit/_commit_box.html.haml
@@ -28,7 +28,7 @@
= link_to project_tree_path(@project, @commit), class: "btn btn-default append-right-10 d-none d-sm-none d-md-inline" do
#{ _('Browse files') }
.dropdown.inline
- %a.btn.btn-default.dropdown-toggle.qa-options-button{ data: { toggle: "dropdown" } }
+ %a.btn.btn-default.dropdown-toggle.qa-options-button.d-md-inline{ data: { toggle: "dropdown" } }
%span= _('Options')
= icon('caret-down')
%ul.dropdown-menu.dropdown-menu-right
diff --git a/app/views/shared/_email_with_badge.html.haml b/app/views/shared/_email_with_badge.html.haml
index ad863b1967d..294fe74a5ca 100644
--- a/app/views/shared/_email_with_badge.html.haml
+++ b/app/views/shared/_email_with_badge.html.haml
@@ -1,6 +1,6 @@
- css_classes = %w(badge badge-verification-status)
- css_classes << (verified ? 'verified': 'unverified')
-- text = verified ? 'Verified' : 'Unverified'
+- text = verified ? _('Verified') : _('Unverified')
.email-badge
.email-badge-email= email
diff --git a/app/views/shared/milestones/_deprecation_message.html.haml b/app/views/shared/milestones/_deprecation_message.html.haml
index 4a8f90937ea..acd90fa9178 100644
--- a/app/views/shared/milestones/_deprecation_message.html.haml
+++ b/app/views/shared/milestones/_deprecation_message.html.haml
@@ -11,4 +11,5 @@
%ol.milestone-popover-instructions-list.append-bottom-0
%li= _('Click any <strong>project name</strong> in the project list below to navigate to the project milestone.').html_safe
%li= _('Click the <strong>Promote</strong> button in the top right corner to promote it to a group milestone.').html_safe
+ %hr.popover-hr
.milestone-popover-footer= link_to _('Learn more'), help_page_url('user/project/milestones/index', anchor: 'promoting-project-milestones-to-group-milestones'), class: 'btn btn-link prepend-left-0', target: '_blank'
diff --git a/changelogs/archive.md b/changelogs/archive.md
index dd7c21dabd6..e36e859a351 100644
--- a/changelogs/archive.md
+++ b/changelogs/archive.md
@@ -274,7 +274,7 @@
- Pass variables from deployment project services to CI runner. !8107
- New Gitea importer. !8116
- Introduce "Set up autodeploy" button to help configure GitLab CI for deployment. !8135
-- Prevent enviroment table to overflow when name has underscores. !8142
+- Prevent environment table to overflow when name has underscores. !8142
- Fix missing service error importing from EE to CE. !8144
- Milestoneish SQL performance partially improved and memoized. !8146
- Allow unauthenticated access to Repositories API GET endpoints. !8148
@@ -562,7 +562,7 @@
- Fix broken issue/merge request links in JIRA comments. !6143 (Brian Kintz)
- Fix filtering of milestones with quotes in title (airatshigapov)
- Fix issue boards dragging bug in Safari
-- Refactor less readable existance checking code from CoffeeScript !6289 (jlogandavison)
+- Refactor less readable existence checking code from CoffeeScript !6289 (jlogandavison)
- Update mail_room and enable sentinel support to Reply By Email (!7101)
- Add task completion status in Issues and Merge Requests tabs: "X of Y tasks completed" (!6527, @gmesalazar)
- Simpler arguments passed to named_route on toggle_award_url helper method
@@ -956,7 +956,7 @@
## 8.12.0 (2016-09-22)
- - Removes inconsistency regarding tagging immediatelly as merged once you create a new branch. !6408
+ - Removes inconsistency regarding tagging immediately as merged once you create a new branch. !6408
- Update the rouge gem to 2.0.6, which adds highlighting support for JSX, Prometheus, and others. !6251
- Only check :can_resolve permission if the note is resolvable
- Bump fog-aws to v0.11.0 to support ap-south-1 region
@@ -1389,7 +1389,7 @@
- Fix notification_service argument error of declined invitation emails
- Fix a memory leak caused by Banzai::Filter::SanitizationFilter
- Speed up todos queries by limiting the projects set we join with
- - Ensure file editing in UI does not overwrite commited changes without warning user
+ - Ensure file editing in UI does not overwrite committed changes without warning user
- Eliminate unneeded calls to Repository#blob_at when listing commits with no path
- Update gitlab_git gem to 10.4.7
- Simplify SQL queries of marking a todo as done
@@ -2076,7 +2076,7 @@
- Don't show forks button when user can't view forks
- Fix atom feed links and rendering
- Files over 5MB can only be viewed in their raw form, files over 1MB without highlighting !3718
- - Add support for supressing text diffs using .gitattributes on the default branch (Matt Oakes)
+ - Add support for suppressing text diffs using .gitattributes on the default branch (Matt Oakes)
- Add eager load paths to help prevent dependency load issues in Sidekiq workers. !3724
- Added multiple colors for labels in dropdowns when dups happen.
- Show commits in the same order as `git log`
@@ -2194,7 +2194,7 @@
- All images in discussions and wikis now link to their source files !3464 (Connor Shea).
- Return status code 303 after a branch DELETE operation to avoid project deletion (Stan Hu)
- Add setting for customizing the list of trusted proxies !3524
- - Allow projects to be transfered to a lower visibility level group
+ - Allow projects to be transferred to a lower visibility level group
- Fix `signed_in_ip` being set to 127.0.0.1 when using a reverse proxy !3524
- Improved Markdown rendering performance !3389
- Make shared runners text in box configurable
@@ -2209,7 +2209,7 @@
- API: Ability to update a group (Robert Schilling)
- API: Ability to move issues (Robert Schilling)
- Fix Error 500 after renaming a project path (Stan Hu)
- - Fix a bug whith trailing slash in teamcity_url (Charles May)
+ - Fix a bug with trailing slash in teamcity_url (Charles May)
- Allow back dating on issues when created or updated through the API
- Allow back dating on issue notes when created through the API
- Propose license template when creating a new LICENSE file
@@ -2219,7 +2219,7 @@
- Allow SAML to handle external users based on user's information !3530
- Allow Omniauth providers to be marked as `external` !3657
- Add endpoints to archive or unarchive a project !3372
- - Fix a bug whith trailing slash in bamboo_url
+ - Fix a bug with trailing slash in bamboo_url
- Add links to CI setup documentation from project settings and builds pages
- Display project members page to all members
- Handle nil descriptions in Slack issue messages (Stan Hu)
@@ -2610,7 +2610,7 @@
- Fixed logo animation on Safari (Roman Rott)
- Fix Merge When Succeeded when multiple stages
- Hide remove source branch button when the MR is merged but new commits are pushed (Zeger-Jan van de Weg)
- - In seach autocomplete show only groups and projects you are member of
+ - In search autocomplete show only groups and projects you are member of
- Don't process cross-reference notes from forks
- Fix: init.d script not working on OS X
- Faster snippet search
@@ -2870,7 +2870,7 @@
- Bump Redis requirement to 2.8 for Sidekiq 4 (Stan Hu)
- Fix: Assignee selector is empty when 'Unassigned' is selected (Jose Corcuera)
- WIP identifier on merge requests no longer requires trailing space
- - Add rake tasks for git repository maintainance (Zeger-Jan van de Weg)
+ - Add rake tasks for git repository maintenance (Zeger-Jan van de Weg)
- Fix 500 error when update group member permission
- Fix: As an admin, cannot add oneself as a member to a group/project
- Trim leading and trailing whitespace of milestone and issueable titles (Jose Corcuera)
@@ -3199,7 +3199,7 @@
- Sort issues by creation date in Bitbucket importer (Stan Hu)
- Prevent too many redirects upon login when home page URL is set to external_url (Stan Hu)
- Improve dropdown positioning on the project home page (Hannes Rosenögger)
- - Upgrade browser gem to 1.0.0 to avoid warning in IE11 compatibilty mode (Stan Hu)
+ - Upgrade browser gem to 1.0.0 to avoid warning in IE11 compatibility mode (Stan Hu)
- Remove user OAuth tokens from the database and request new tokens each session (Stan Hu)
- Restrict users API endpoints to use integer IDs (Stan Hu)
- Only show recent push event if the branch still exists or a recent merge request has not been created (Stan Hu)
@@ -3209,7 +3209,7 @@
- Ability to fetch merge requests from refs/merge-requests/:id
- Allow displaying of archived projects in the admin interface (Artem Sidorenko)
- Allow configuration of import sources for new projects (Artem Sidorenko)
- - Search for comments should be case insensetive
+ - Search for comments should be case insensitive
- Create cross-reference for closing references on commits pushed to non-default branches (Maël Valais)
- Ability to search milestones
- Gracefully handle SMTP user input errors (e.g. incorrect email addresses) to prevent Sidekiq retries (Stan Hu)
@@ -3477,7 +3477,7 @@
- Update Asciidoctor gem to version 1.5.2. (Jakub Jirutka)
- Fix resolving of relative links to repository files in AsciiDoc documents. (Jakub Jirutka)
- Use the user list from the target project in a merge request (Stan Hu)
-- Default extention for wiki pages is now .md instead of .markdown (Jeroen van Baarsen)
+- Default extension for wiki pages is now .md instead of .markdown (Jeroen van Baarsen)
- Add validation to wiki page creation (only [a-zA-Z0-9/_-] are allowed) (Jeroen van Baarsen)
- Fix new/empty milestones showing 100% completion value (Jonah Bishop)
- Add a note when an Issue or Merge Request's title changes
@@ -3613,7 +3613,7 @@
- Set EmailsOnPush reply-to address to committer email when enabled.
- Fix broken file browsing with a submodule that contains a relative link (Stan Hu)
- Fix persistent XSS vulnerability around profile website URLs.
-- Fix project import URL regex to prevent arbitary local repos from being imported.
+- Fix project import URL regex to prevent arbitrary local repos from being imported.
- Fix directory traversal vulnerability around uploads routes.
- Fix directory traversal vulnerability around help pages.
- Don't leak existence of project via search autocomplete.
@@ -3676,7 +3676,7 @@
- Don't show commit comment button when user is not signed in.
- Fix admin user projects lists.
- Don't leak private group existence by redirecting from namespace controller to group controller.
-- Ability to skip some items from backup (database, respositories or uploads)
+- Ability to skip some items from backup (database, repositories or uploads)
- Archive repositories in background worker.
- Import GitHub, Bitbucket or GitLab.com projects owned by authenticated user into current namespace.
- Project labels are now available over the API under the "tag_list" field (Cristian Medina)
@@ -3701,7 +3701,7 @@
## 7.9.4
-- Security: Fix project import URL regex to prevent arbitary local repos from being imported
+- Security: Fix project import URL regex to prevent arbitrary local repos from being imported
- Fixed issue where only 25 commits would load in file listings
- Fix LDAP identities after config update
@@ -4199,7 +4199,7 @@
- Only masters can rewrite/remove git tags
- Add X-Frame-Options SAMEORIGIN to Nginx config so Sidekiq admin is visible
- UI improvements
-- Case-insensetive search for issues
+- Case-insensitive search for issues
- Update to rails 4.1
- Improve performance of application for projects and groups with a lot of members
- Formally support Ruby 2.1
@@ -4358,7 +4358,7 @@
- Group avatar
- Pygments.rb replaced with highlight.js
- Improve Merge request diff store logic
-- Improve render performnace for MR show page
+- Improve render performances for MR show page
- Fixed Assembla hardcoded project name
- Jira integration documentation
- Refactored app/services
diff --git a/changelogs/unreleased/33064-add-labels-to-note-event-payload.yml b/changelogs/unreleased/33064-add-labels-to-note-event-payload.yml
new file mode 100644
index 00000000000..e0a6253e1ef
--- /dev/null
+++ b/changelogs/unreleased/33064-add-labels-to-note-event-payload.yml
@@ -0,0 +1,5 @@
+---
+title: Add labels to note event payload
+merge_request: 29384
+author: Sujay Patel
+type: added
diff --git a/changelogs/unreleased/5615-non-admins-only-archieve-ce.yml b/changelogs/unreleased/5615-non-admins-only-archieve-ce.yml
new file mode 100644
index 00000000000..ac1aa249b82
--- /dev/null
+++ b/changelogs/unreleased/5615-non-admins-only-archieve-ce.yml
@@ -0,0 +1,5 @@
+---
+title: Add deletion protection setting column to application_settings table
+merge_request: 29268
+author:
+type: other
diff --git a/changelogs/unreleased/58433-email-notifications-do-not-work-properly-issue-due-date.yml b/changelogs/unreleased/58433-email-notifications-do-not-work-properly-issue-due-date.yml
new file mode 100644
index 00000000000..4579721446a
--- /dev/null
+++ b/changelogs/unreleased/58433-email-notifications-do-not-work-properly-issue-due-date.yml
@@ -0,0 +1,5 @@
+---
+title: Fix email notifications for user excluded actions
+merge_request: 28835
+author:
+type: fixed
diff --git a/changelogs/unreleased/58984-doc-missing-milestones-and-labels-links.yml b/changelogs/unreleased/58984-doc-missing-milestones-and-labels-links.yml
new file mode 100644
index 00000000000..6b74303c16e
--- /dev/null
+++ b/changelogs/unreleased/58984-doc-missing-milestones-and-labels-links.yml
@@ -0,0 +1,5 @@
+---
+title: Document when milestones and labels links are missing
+merge_request: 29355
+author:
+type: other
diff --git a/changelogs/unreleased/59651-remove-unnecessary-decimal-places-on-chart-axes.yml b/changelogs/unreleased/59651-remove-unnecessary-decimal-places-on-chart-axes.yml
new file mode 100644
index 00000000000..fea34099135
--- /dev/null
+++ b/changelogs/unreleased/59651-remove-unnecessary-decimal-places-on-chart-axes.yml
@@ -0,0 +1,5 @@
+---
+title: Remove unnecessary decimals on Metrics chart axis
+merge_request: 29468
+author:
+type: fixed
diff --git a/changelogs/unreleased/61072-link-to-user-profile-not-distinguishable-on-latest-commit-widget.yml b/changelogs/unreleased/61072-link-to-user-profile-not-distinguishable-on-latest-commit-widget.yml
new file mode 100644
index 00000000000..5285ac767cc
--- /dev/null
+++ b/changelogs/unreleased/61072-link-to-user-profile-not-distinguishable-on-latest-commit-widget.yml
@@ -0,0 +1,5 @@
+---
+title: User link styling for commits
+merge_request: 29150
+author:
+type: other
diff --git a/changelogs/unreleased/61246-fix-label-click-scroll-to-top.yml b/changelogs/unreleased/61246-fix-label-click-scroll-to-top.yml
deleted file mode 100644
index 7fa15e1c0fd..00000000000
--- a/changelogs/unreleased/61246-fix-label-click-scroll-to-top.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix label click scrolling to top
-merge_request: 29202
-author:
-type: fixed
diff --git a/changelogs/unreleased/62144-fix-option-dropdown-button-size.yml b/changelogs/unreleased/62144-fix-option-dropdown-button-size.yml
new file mode 100644
index 00000000000..86d8f4536f9
--- /dev/null
+++ b/changelogs/unreleased/62144-fix-option-dropdown-button-size.yml
@@ -0,0 +1,5 @@
+---
+title: Fix inconsistent option dropdown button height to match adjacent button
+merge_request: 29096
+author:
+type: fixed
diff --git a/changelogs/unreleased/62154-fe-create-fix-long-branch-name-in-dropdown.yml b/changelogs/unreleased/62154-fe-create-fix-long-branch-name-in-dropdown.yml
new file mode 100644
index 00000000000..1d951c1dc24
--- /dev/null
+++ b/changelogs/unreleased/62154-fe-create-fix-long-branch-name-in-dropdown.yml
@@ -0,0 +1,6 @@
+---
+title: Add support to view entirety of long branch name in dropdown instead of it
+ being cut off
+merge_request: 29069
+author:
+type: fixed
diff --git a/changelogs/unreleased/62300-target-area-for-dropdown-list-items-is-too-small-on-metrics-dashboard.yml b/changelogs/unreleased/62300-target-area-for-dropdown-list-items-is-too-small-on-metrics-dashboard.yml
new file mode 100644
index 00000000000..7944e6faa27
--- /dev/null
+++ b/changelogs/unreleased/62300-target-area-for-dropdown-list-items-is-too-small-on-metrics-dashboard.yml
@@ -0,0 +1,5 @@
+---
+title: Enlarge metrics time-window dropdown links
+merge_request: 29458
+author:
+type: fixed
diff --git a/changelogs/unreleased/62713-fix-uninstalling-cluster-apps.yml b/changelogs/unreleased/62713-fix-uninstalling-cluster-apps.yml
deleted file mode 100644
index 45fa668ae85..00000000000
--- a/changelogs/unreleased/62713-fix-uninstalling-cluster-apps.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix connection to Tiller error while uninstalling
-merge_request: 29131
-author:
-type: fixed
diff --git a/changelogs/unreleased/62788-clean-up-pagination.yml b/changelogs/unreleased/62788-clean-up-pagination.yml
new file mode 100644
index 00000000000..05e3a4527b8
--- /dev/null
+++ b/changelogs/unreleased/62788-clean-up-pagination.yml
@@ -0,0 +1,5 @@
+---
+title: Moves the table pagination shared component
+merge_request:
+author:
+type: other
diff --git a/changelogs/unreleased/62788-graphql-pagination.yml b/changelogs/unreleased/62788-graphql-pagination.yml
new file mode 100644
index 00000000000..a7bc317a08f
--- /dev/null
+++ b/changelogs/unreleased/62788-graphql-pagination.yml
@@ -0,0 +1,5 @@
+---
+title: Adds pagination component for graphql api
+merge_request: 29277
+author:
+type: added
diff --git a/changelogs/unreleased/62974-follow-up-from-wip-align-merge-request-icons-and-text.yml b/changelogs/unreleased/62974-follow-up-from-wip-align-merge-request-icons-and-text.yml
new file mode 100644
index 00000000000..811986e6857
--- /dev/null
+++ b/changelogs/unreleased/62974-follow-up-from-wip-align-merge-request-icons-and-text.yml
@@ -0,0 +1,5 @@
+---
+title: 'Make margin between buttons consistent'
+merge_request: 29378
+author:
+type: other
diff --git a/changelogs/unreleased/9186-implement-atmtwps-state-to-mr-widget.yml b/changelogs/unreleased/9186-implement-atmtwps-state-to-mr-widget.yml
new file mode 100644
index 00000000000..2c1d56f197e
--- /dev/null
+++ b/changelogs/unreleased/9186-implement-atmtwps-state-to-mr-widget.yml
@@ -0,0 +1,5 @@
+---
+title: Update the merge request widget's "Merge" button to support merge trains
+merge_request: 27594
+author:
+type: added
diff --git a/changelogs/unreleased/ac-63020-typeerror-nil-can-t-be-coerced-into-integer.yml b/changelogs/unreleased/ac-63020-typeerror-nil-can-t-be-coerced-into-integer.yml
new file mode 100644
index 00000000000..51ac2358fba
--- /dev/null
+++ b/changelogs/unreleased/ac-63020-typeerror-nil-can-t-be-coerced-into-integer.yml
@@ -0,0 +1,5 @@
+---
+title: Fix nil coercion updating storage size on project statistics
+merge_request: 29425
+author:
+type: fixed
diff --git a/changelogs/unreleased/add-lfs-blob-ids-to-tree-type.yml b/changelogs/unreleased/add-lfs-blob-ids-to-tree-type.yml
new file mode 100644
index 00000000000..14a5ef1cef3
--- /dev/null
+++ b/changelogs/unreleased/add-lfs-blob-ids-to-tree-type.yml
@@ -0,0 +1,5 @@
+---
+title: Add LFS oid to GraphQL blob type
+merge_request: 28666
+author:
+type: added
diff --git a/changelogs/unreleased/allow-emoji-in-references.yml b/changelogs/unreleased/allow-emoji-in-references.yml
new file mode 100644
index 00000000000..3116b346c00
--- /dev/null
+++ b/changelogs/unreleased/allow-emoji-in-references.yml
@@ -0,0 +1,5 @@
+---
+title: Allow references to labels and milestones to contain emoji
+merge_request: 29284
+author:
+type: changed
diff --git a/changelogs/unreleased/cancel-auto-merge-when-branch-is-changed.yml b/changelogs/unreleased/cancel-auto-merge-when-branch-is-changed.yml
new file mode 100644
index 00000000000..c3c6e4322a2
--- /dev/null
+++ b/changelogs/unreleased/cancel-auto-merge-when-branch-is-changed.yml
@@ -0,0 +1,5 @@
+---
+title: Cancel Auto Merge when target branch is changed
+merge_request: 29416
+author:
+type: fixed
diff --git a/changelogs/unreleased/expose-project-git-depth-via-api.yml b/changelogs/unreleased/expose-project-git-depth-via-api.yml
new file mode 100644
index 00000000000..e9d158fda16
--- /dev/null
+++ b/changelogs/unreleased/expose-project-git-depth-via-api.yml
@@ -0,0 +1,5 @@
+---
+title: Get and edit ci_default_git_depth via project API
+merge_request: 29353
+author:
+type: added
diff --git a/changelogs/unreleased/fe-fix-gl-dropdown-scrolling-to-top.yml b/changelogs/unreleased/fe-fix-gl-dropdown-scrolling-to-top.yml
new file mode 100644
index 00000000000..4125b4241e6
--- /dev/null
+++ b/changelogs/unreleased/fe-fix-gl-dropdown-scrolling-to-top.yml
@@ -0,0 +1,5 @@
+---
+title: Fix scrolling to top on assignee change
+merge_request: 29500
+author:
+type: fixed
diff --git a/changelogs/unreleased/fix-diverged-branch-locals.yml b/changelogs/unreleased/fix-diverged-branch-locals.yml
new file mode 100644
index 00000000000..719d669fad3
--- /dev/null
+++ b/changelogs/unreleased/fix-diverged-branch-locals.yml
@@ -0,0 +1,5 @@
+---
+title: Fix diverged branch locals
+merge_request: 29508
+author:
+type: fixed
diff --git a/changelogs/unreleased/fix-issue-mr-badge.yml b/changelogs/unreleased/fix-issue-mr-badge.yml
new file mode 100644
index 00000000000..e777f52f173
--- /dev/null
+++ b/changelogs/unreleased/fix-issue-mr-badge.yml
@@ -0,0 +1,5 @@
+---
+title: Use grid and correct border radius for status badge
+merge_request:
+author:
+type: other
diff --git a/changelogs/unreleased/fix-pipeline-schedule-owner-is-nil.yml b/changelogs/unreleased/fix-pipeline-schedule-owner-is-nil.yml
new file mode 100644
index 00000000000..5c8644d2860
--- /dev/null
+++ b/changelogs/unreleased/fix-pipeline-schedule-owner-is-nil.yml
@@ -0,0 +1,5 @@
+---
+title: Fix pipeline schedules when owner is nil
+merge_request:
+author:
+type: fixed
diff --git a/changelogs/unreleased/i18n-email-of-user-profile.yml b/changelogs/unreleased/i18n-email-of-user-profile.yml
new file mode 100644
index 00000000000..6cb718843d5
--- /dev/null
+++ b/changelogs/unreleased/i18n-email-of-user-profile.yml
@@ -0,0 +1,5 @@
+---
+title: Externalize strings of email page in user profile
+merge_request: 28587
+author: antony liu
+type: other
diff --git a/changelogs/unreleased/ignore-artifact-attirbutes-in-project-import-export.yml b/changelogs/unreleased/ignore-artifact-attirbutes-in-project-import-export.yml
new file mode 100644
index 00000000000..536aae03f59
--- /dev/null
+++ b/changelogs/unreleased/ignore-artifact-attirbutes-in-project-import-export.yml
@@ -0,0 +1,5 @@
+---
+title: Ignore legacy artifact columns in Project Import/Export
+merge_request: 29427
+author:
+type: fixed
diff --git a/changelogs/unreleased/jc-migration-for-source-project-id.yml b/changelogs/unreleased/jc-migration-for-source-project-id.yml
new file mode 100644
index 00000000000..3e2e8ebfcc5
--- /dev/null
+++ b/changelogs/unreleased/jc-migration-for-source-project-id.yml
@@ -0,0 +1,5 @@
+---
+title: Fix null source_project_id in pool_repositories
+merge_request: 29157
+author:
+type: other
diff --git a/changelogs/unreleased/osw-avoid-encoding-errors-on-merge-to-ref-service.yml b/changelogs/unreleased/osw-avoid-encoding-errors-on-merge-to-ref-service.yml
new file mode 100644
index 00000000000..176c8bf36f7
--- /dev/null
+++ b/changelogs/unreleased/osw-avoid-encoding-errors-on-merge-to-ref-service.yml
@@ -0,0 +1,5 @@
+---
+title: Handle encoding errors for MergeToRefService
+merge_request: 29440
+author:
+type: fixed
diff --git a/changelogs/unreleased/osw-fix-post-dep-migration-with-timeout.yml b/changelogs/unreleased/osw-fix-post-dep-migration-with-timeout.yml
new file mode 100644
index 00000000000..6b37bb11ad5
--- /dev/null
+++ b/changelogs/unreleased/osw-fix-post-dep-migration-with-timeout.yml
@@ -0,0 +1,5 @@
+---
+title: Avoid DB timeouts when scheduling migrations
+merge_request: 29437
+author:
+type: fixed
diff --git a/changelogs/unreleased/osw-sync-merge-ref-upon-mergeability-check.yml b/changelogs/unreleased/osw-sync-merge-ref-upon-mergeability-check.yml
deleted file mode 100644
index 1f40089adb8..00000000000
--- a/changelogs/unreleased/osw-sync-merge-ref-upon-mergeability-check.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Sync merge ref upon mergeability check
-merge_request: 28513
-author:
-type: added
diff --git a/changelogs/unreleased/patch-65.yml b/changelogs/unreleased/patch-65.yml
new file mode 100644
index 00000000000..9ce628a6541
--- /dev/null
+++ b/changelogs/unreleased/patch-65.yml
@@ -0,0 +1,5 @@
+---
+title: Show tooltip on truncated commit title
+merge_request: 28865
+author: Timofey Trofimov
+type: other
diff --git a/changelogs/unreleased/revert-git-depth-for-merge-request.yml b/changelogs/unreleased/revert-git-depth-for-merge-request.yml
deleted file mode 100644
index 3a258dff358..00000000000
--- a/changelogs/unreleased/revert-git-depth-for-merge-request.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Remove a default git depth in Pipelines for merge requests
-merge_request: 28926
-author:
-type: fixed
diff --git a/changelogs/unreleased/sh-add-backtrace-to-sql-queries.yml b/changelogs/unreleased/sh-add-backtrace-to-sql-queries.yml
new file mode 100644
index 00000000000..d4ca027d1b9
--- /dev/null
+++ b/changelogs/unreleased/sh-add-backtrace-to-sql-queries.yml
@@ -0,0 +1,5 @@
+---
+title: Add backtraces to Peek performance bar for SQL calls
+merge_request:
+author:
+type: added
diff --git a/changelogs/unreleased/sh-fix-fogbugz-import.yml b/changelogs/unreleased/sh-fix-fogbugz-import.yml
new file mode 100644
index 00000000000..1ac730fca24
--- /dev/null
+++ b/changelogs/unreleased/sh-fix-fogbugz-import.yml
@@ -0,0 +1,5 @@
+---
+title: Fix Fogbugz Importer not working
+merge_request: 29383
+author:
+type: fixed
diff --git a/changelogs/unreleased/sh-fix-openid-connect-defaults.yml b/changelogs/unreleased/sh-fix-openid-connect-defaults.yml
deleted file mode 100644
index 1ed977c9be6..00000000000
--- a/changelogs/unreleased/sh-fix-openid-connect-defaults.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Make OpenID Connect work without requiring a name
-merge_request: 29312
-author:
-type: fixed
diff --git a/changelogs/unreleased/sh-fix-resolve-button-not-available.yml b/changelogs/unreleased/sh-fix-resolve-button-not-available.yml
new file mode 100644
index 00000000000..85a9007f570
--- /dev/null
+++ b/changelogs/unreleased/sh-fix-resolve-button-not-available.yml
@@ -0,0 +1,5 @@
+---
+title: Fix "Resolve conflicts" button not appearing for some users
+merge_request: 29535
+author:
+type: fixed
diff --git a/changelogs/unreleased/sh-fix-utf-8-encoding-resolve-conflicts.yml b/changelogs/unreleased/sh-fix-utf-8-encoding-resolve-conflicts.yml
new file mode 100644
index 00000000000..31039099788
--- /dev/null
+++ b/changelogs/unreleased/sh-fix-utf-8-encoding-resolve-conflicts.yml
@@ -0,0 +1,5 @@
+---
+title: Fix UTF-8 conversion issues when resolving conflicts
+merge_request: 29453
+author:
+type: fixed
diff --git a/changelogs/unreleased/sh-project-import-visibility-error.yml b/changelogs/unreleased/sh-project-import-visibility-error.yml
deleted file mode 100644
index eb7e001c6aa..00000000000
--- a/changelogs/unreleased/sh-project-import-visibility-error.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix invalid visibility string comparison in project import
-merge_request: 28612
-author:
-type: fixed
diff --git a/changelogs/unreleased/upgrade-pages-to-v1-6-1.yml b/changelogs/unreleased/upgrade-pages-to-v1-6-1.yml
new file mode 100644
index 00000000000..0ab58bb50d8
--- /dev/null
+++ b/changelogs/unreleased/upgrade-pages-to-v1-6-1.yml
@@ -0,0 +1,5 @@
+---
+title: Update GitLab Pages to v1.6.1
+merge_request: 29559
+author:
+type: other
diff --git a/config/initializers/rack_timeout.rb b/config/initializers/rack_timeout.rb
index 5c4f2dd708c..58f46b55725 100644
--- a/config/initializers/rack_timeout.rb
+++ b/config/initializers/rack_timeout.rb
@@ -18,6 +18,6 @@ if defined?(::Puma) && !Rails.env.test?
wait_timeout: 90)
end
- observer = Gitlab::RackTimeoutObserver.new
+ observer = Gitlab::Cluster::RackTimeoutObserver.new
Rack::Timeout.register_state_change_observer(:gitlab_rack_timeout, &observer.callback)
end
diff --git a/config/puma.example.development.rb b/config/puma.example.development.rb
index 490c940077a..9df24bf74e3 100644
--- a/config/puma.example.development.rb
+++ b/config/puma.example.development.rb
@@ -42,7 +42,6 @@ bind 'unix:///home/git/gitlab.socket'
workers 2
require_relative "/home/git/gitlab/lib/gitlab/cluster/lifecycle_events"
-require_relative "/home/git/gitlab/lib/gitlab/cluster/puma_worker_killer_initializer"
on_restart do
# Signal application hooks that we're about to restart
diff --git a/config/routes/project.rb b/config/routes/project.rb
index d44ff62bc2a..a1e769f6ca3 100644
--- a/config/routes/project.rb
+++ b/config/routes/project.rb
@@ -330,7 +330,7 @@ constraints(::Constraints::ProjectUrlConstrainer.new) do
get :metrics_dashboard
get '/terminal.ws/authorize', to: 'environments#terminal_websocket_authorize', constraints: { format: nil }
- get '/prometheus/api/v1/*proxy_path', to: 'environments/prometheus_api#proxy'
+ get '/prometheus/api/v1/*proxy_path', to: 'environments/prometheus_api#proxy', as: :prometheus_api
end
collection do
diff --git a/db/migrate/20190604184643_fix_pool_repository_source_project_id.rb b/db/migrate/20190604184643_fix_pool_repository_source_project_id.rb
new file mode 100644
index 00000000000..30244760e6b
--- /dev/null
+++ b/db/migrate/20190604184643_fix_pool_repository_source_project_id.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+# See http://doc.gitlab.com/ce/development/migration_style_guide.html
+# for more information on how to write migrations for GitLab.
+
+class FixPoolRepositorySourceProjectId < ActiveRecord::Migration[5.1]
+ include Gitlab::Database::MigrationHelpers
+
+ # Set this constant to true if this migration requires downtime.
+ DOWNTIME = false
+
+ def up
+ execute "UPDATE pool_repositories SET source_project_id = (SELECT MIN(id) FROM projects WHERE pool_repository_id = pool_repositories.id) WHERE pool_repositories.source_project_id IS NULL"
+ end
+
+ def down
+ # nothing to do her
+ end
+end
diff --git a/db/migrate/20190605104727_add_default_project_deletion_protection_to_application_settings.rb b/db/migrate/20190605104727_add_default_project_deletion_protection_to_application_settings.rb
new file mode 100644
index 00000000000..ee04b49813b
--- /dev/null
+++ b/db/migrate/20190605104727_add_default_project_deletion_protection_to_application_settings.rb
@@ -0,0 +1,20 @@
+# frozen_string_literal: true
+
+# See http://doc.gitlab.com/ce/development/migration_style_guide.html
+# for more information on how to write migrations for GitLab.
+
+class AddDefaultProjectDeletionProtectionToApplicationSettings < ActiveRecord::Migration[5.1]
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+
+ disable_ddl_transaction!
+
+ def up
+ add_column_with_default :application_settings, :default_project_deletion_protection, :boolean, default: false, allow_null: false
+ end
+
+ def down
+ remove_column :application_settings, :default_project_deletion_protection
+ end
+end
diff --git a/db/migrate/20190611161641_add_target_project_id_to_merge_trains.rb b/db/migrate/20190611161641_add_target_project_id_to_merge_trains.rb
new file mode 100644
index 00000000000..c200208e4c3
--- /dev/null
+++ b/db/migrate/20190611161641_add_target_project_id_to_merge_trains.rb
@@ -0,0 +1,14 @@
+# frozen_string_literal: true
+
+class AddTargetProjectIdToMergeTrains < ActiveRecord::Migration[5.1]
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+
+ def change
+ # rubocop: disable Rails/NotNullColumn
+ add_reference :merge_trains, :target_project, null: false, index: true, foreign_key: { on_delete: :cascade, to_table: :projects }, type: :integer
+ add_column :merge_trains, :target_branch, :text, null: false
+ # rubocop: enable Rails/NotNullColumn
+ end
+end
diff --git a/db/post_migrate/20190528180441_enqueue_reset_merge_status.rb b/db/post_migrate/20190528180441_enqueue_reset_merge_status.rb
index 1b668d85bac..a3d2f497806 100644
--- a/db/post_migrate/20190528180441_enqueue_reset_merge_status.rb
+++ b/db/post_migrate/20190528180441_enqueue_reset_merge_status.rb
@@ -16,15 +16,10 @@ class EnqueueResetMergeStatus < ActiveRecord::Migration[5.1]
def up
say 'Scheduling `ResetMergeStatus` jobs'
- # We currently have around 135_000 opened, mergeable MRs in GitLab.com. This iteration
- # will schedule around 13 batches of 10_000 MRs, which should take around 1 hour to
- # complete.
- relation = MergeRequest.where(state: 'opened', merge_status: 'can_be_merged')
-
- relation.each_batch(of: BATCH_SIZE) do |batch, index|
- range = batch.pluck('MIN(id)', 'MAX(id)').first
-
- BackgroundMigrationWorker.perform_in(index * DELAY_INTERVAL, MIGRATION, range)
- end
+ # We currently have more than ~5_000_000 merge request records on GitLab.com.
+ # This means it'll schedule ~500 jobs (10k MRs each) with a 5 minutes gap,
+ # so this should take ~41 hours for all background migrations to complete.
+ # ((5_000_000 / 10_000) * 5) / 60 => 41.6666..
+ queue_background_migration_jobs_by_range_at_intervals(MergeRequest, MIGRATION, DELAY_INTERVAL, batch_size: BATCH_SIZE)
end
end
diff --git a/db/schema.rb b/db/schema.rb
index 22d0cddb7a0..c57a73c66da 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
-ActiveRecord::Schema.define(version: 20190530154715) do
+ActiveRecord::Schema.define(version: 20190611161641) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
@@ -194,6 +194,7 @@ ActiveRecord::Schema.define(version: 20190530154715) do
t.text "encrypted_lets_encrypt_private_key"
t.text "encrypted_lets_encrypt_private_key_iv"
t.boolean "dns_rebinding_protection_enabled", default: true, null: false
+ t.boolean "default_project_deletion_protection", default: false, null: false
t.index ["usage_stats_set_by_user_id"], name: "index_application_settings_on_usage_stats_set_by_user_id", using: :btree
end
@@ -1387,8 +1388,11 @@ ActiveRecord::Schema.define(version: 20190530154715) do
t.integer "pipeline_id"
t.datetime_with_timezone "created_at", null: false
t.datetime_with_timezone "updated_at", null: false
+ t.integer "target_project_id", null: false
+ t.text "target_branch", null: false
t.index ["merge_request_id"], name: "index_merge_trains_on_merge_request_id", unique: true, using: :btree
t.index ["pipeline_id"], name: "index_merge_trains_on_pipeline_id", using: :btree
+ t.index ["target_project_id"], name: "index_merge_trains_on_target_project_id", using: :btree
t.index ["user_id"], name: "index_merge_trains_on_user_id", using: :btree
end
@@ -2570,6 +2574,7 @@ ActiveRecord::Schema.define(version: 20190530154715) do
add_foreign_key "merge_requests_closing_issues", "merge_requests", on_delete: :cascade
add_foreign_key "merge_trains", "ci_pipelines", column: "pipeline_id", on_delete: :nullify
add_foreign_key "merge_trains", "merge_requests", on_delete: :cascade
+ add_foreign_key "merge_trains", "projects", column: "target_project_id", on_delete: :cascade
add_foreign_key "merge_trains", "users", on_delete: :cascade
add_foreign_key "milestones", "namespaces", column: "group_id", name: "fk_95650a40d4", on_delete: :cascade
add_foreign_key "milestones", "projects", name: "fk_9bd0a0c791", on_delete: :cascade
diff --git a/doc/administration/high_availability/README.md b/doc/administration/high_availability/README.md
index 002deeaf945..d9c80b1ec59 100644
--- a/doc/administration/high_availability/README.md
+++ b/doc/administration/high_availability/README.md
@@ -26,8 +26,7 @@ experience with GitLab.com and Enterprise Edition on-premises customers.
For a detailed insight into how GitLab scales and configures GitLab.com, you can
watch [this 1 hour Q&A](https://www.youtube.com/watch?v=uCU8jdYzpac)
-with [John Northrup](https://gitlab.com/northrup), one of our infrastructure
-engineers, and live questions coming in from some of our customers.
+with [John Northrup](https://gitlab.com/northrup), and live questions coming in from some of our customers.
## GitLab Components
diff --git a/doc/administration/high_availability/nfs.md b/doc/administration/high_availability/nfs.md
index 490c2699458..3013ce63bd5 100644
--- a/doc/administration/high_availability/nfs.md
+++ b/doc/administration/high_availability/nfs.md
@@ -37,6 +37,14 @@ options:
circumstances it could lead to data loss if a failure occurs before data has
synced.
+Due to the complexities of running Omnibus with LDAP and the complexities of
+maintaining ID mapping without LDAP, in most cases you should enable numeric UIDs
+and GIDs (which is off by default in some cases) for simplified permission
+management between systems:
+
+ - [NetApp instructions](https://library.netapp.com/ecmdocs/ECMP1401220/html/GUID-24367A9F-E17B-4725-ADC1-02D86F56F78E.html)
+ - For non-NetApp devices, disable NFSv4 `idmapping` by performing opposite of [enable NFSv4 idmapper](https://wiki.archlinux.org/index.php/NFS#Enabling_NFSv4_idmapping)
+
### Improving NFS performance with GitLab
NOTE: **Note:** This is only available starting in certain versions of GitLab: 11.5.11,
diff --git a/doc/administration/index.md b/doc/administration/index.md
index 95a0e84deb6..06d900b152d 100644
--- a/doc/administration/index.md
+++ b/doc/administration/index.md
@@ -36,7 +36,7 @@ Learn how to install, configure, update, and maintain your GitLab instance.
- [Omnibus support for external MySQL DB](https://docs.gitlab.com/omnibus/settings/database.html#using-a-mysql-database-management-server-enterprise-edition-only): Omnibus package supports configuring an external MySQL database. **[STARTER ONLY]**
- [Omnibus support for log forwarding](https://docs.gitlab.com/omnibus/settings/logs.html#udp-log-shipping-gitlab-enterprise-edition-only) **[STARTER ONLY]**
- [High Availability](high_availability/README.md): Configure multiple servers for scaling or high availability.
- - [High Availability on AWS](../university/high-availability/aws/README.md): Set up GitLab HA on Amazon AWS.
+ - [Installing GitLab HA on Amazon Web Services (AWS)](../install/aws/index.md): Set up GitLab High Availability on Amazon AWS.
- [Geo](geo/replication/index.md): Replicate your GitLab instance to other geographic locations as a read-only fully operational version. **[PREMIUM ONLY]**
- [Disaster Recovery](geo/disaster_recovery/index.md): Quickly fail-over to a different site with minimal effort in a disaster situation. **[PREMIUM ONLY]**
- [Pivotal Tile](../install/pivotal/index.md): Deploy GitLab as a pre-configured appliance using Ops Manager (BOSH) for Pivotal Cloud Foundry. **[PREMIUM ONLY]**
diff --git a/doc/administration/monitoring/performance/index.md b/doc/administration/monitoring/performance/index.md
index f5f0363ed38..ef71ca1d6c3 100644
--- a/doc/administration/monitoring/performance/index.md
+++ b/doc/administration/monitoring/performance/index.md
@@ -14,7 +14,7 @@ documents in order to understand and properly configure GitLab Performance Monit
- [Performance bar](performance_bar.md)
- [Request profiling](request_profiling.md)
->**Note:**
+NOTE: **Note:**
Omnibus GitLab 8.16 includes Prometheus as an additional tool to collect
metrics. It will eventually replace InfluxDB when their metrics collection is
on par. Read more in the [Prometheus documentation](../prometheus/index.md).
diff --git a/doc/administration/monitoring/prometheus/gitlab_metrics.md b/doc/administration/monitoring/prometheus/gitlab_metrics.md
index 3dcd1593099..84b71ae6f1c 100644
--- a/doc/administration/monitoring/prometheus/gitlab_metrics.md
+++ b/doc/administration/monitoring/prometheus/gitlab_metrics.md
@@ -125,6 +125,7 @@ When Puma is used instead of Unicorn, following metrics are available:
| puma_max_threads | Gauge | 12.0 | Maximum number of worker threads |
| puma_idle_threads | Gauge | 12.0 | Number of spawned threads which are not processing a request |
| rack_state_total | Gauge | 12.0 | Number of requests in a given rack state |
+| puma_killer_terminations_total | Gauge | 12.0 | Number of workers terminated by PumaWorkerKiller |
## Metrics shared directory
diff --git a/doc/administration/repository_storage_types.md b/doc/administration/repository_storage_types.md
index 4db3cbb9958..38842693d73 100644
--- a/doc/administration/repository_storage_types.md
+++ b/doc/administration/repository_storage_types.md
@@ -106,6 +106,11 @@ enabled for individual projects by executing
be on hashed storage, should not be a fork itself, and hashed storage should be
enabled for all new projects.
+DANGER: **Danger:**
+Do not run `git prune` or `git gc` in pool repositories! This can
+cause data loss in "real" repositories that depend on the pool in
+question.
+
### How to migrate to Hashed Storage
To start a migration, enable Hashed Storage for new projects:
diff --git a/doc/api/merge_requests.md b/doc/api/merge_requests.md
index 96a956ad03a..dd7810c3403 100644
--- a/doc/api/merge_requests.md
+++ b/doc/api/merge_requests.md
@@ -1191,29 +1191,33 @@ Parameters:
}
```
-## Returns the up to date merge-ref HEAD commit
+## Merge to default merge ref path
-Merge the changes between the merge request source and target branches into `refs/merge-requests/:iid/merge`
-ref, of the target project repository, if possible. This ref will have the state the target branch would have if
+Merge the changes between the merge request source and target branches into `refs/merge-requests/:iid/merge`
+ref, of the target project repository. This ref will have the state the target branch would have if
a regular merge action was taken.
-This is not a regular merge action given it doesn't change the merge request target branch state in any manner.
+This is not a regular merge action given it doesn't change the merge request state in any manner.
-This ref (`refs/merge-requests/:iid/merge`) isn't necessarily overwritten when submitting
-requests to this API, though it'll make sure the ref has the latest possible state.
+This ref (`refs/merge-requests/:iid/merge`) is **always** overwritten when submitting
+requests to this API, so none of its state is kept or used in the process.
-If the merge request has conflicts, is empty or already merged, you'll get a `400` and a descriptive error message.
+If the merge request has conflicts, is empty or already merged,
+you'll get a `400` and a descriptive error message. If you don't have permissions to do so,
+you'll get a `403`.
-It returns the HEAD commit of `refs/merge-requests/:iid/merge` in the response body in case of `200`.
+It returns the HEAD commit of `refs/merge-requests/:iid/merge` in the response body in
+case of `200`.
```
-GET /projects/:id/merge_requests/:merge_request_iid/merge_ref
+PUT /projects/:id/merge_requests/:merge_request_iid/merge_to_ref
```
Parameters:
- `id` (required) - The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user
- `merge_request_iid` (required) - Internal ID of MR
+- `merge_commit_message` (optional) - Custom merge commit message
```json
{
diff --git a/doc/api/projects.md b/doc/api/projects.md
index 75669d85803..1d58e390d9e 100644
--- a/doc/api/projects.md
+++ b/doc/api/projects.md
@@ -143,6 +143,7 @@ When the user is authenticated and `simple` is not set this returns something li
"forks_count": 0,
"star_count": 0,
"runners_token": "b8547b1dc37721d05889db52fa2f02",
+ "ci_default_git_depth": 50,
"public_jobs": true,
"shared_with_groups": [],
"only_allow_merge_if_pipeline_succeeds": false,
@@ -225,6 +226,7 @@ When the user is authenticated and `simple` is not set this returns something li
"forks_count": 0,
"star_count": 0,
"runners_token": "b8547b1dc37721d05889db52fa2f02",
+ "ci_default_git_depth": 0,
"public_jobs": true,
"shared_with_groups": [],
"only_allow_merge_if_pipeline_succeeds": false,
@@ -334,6 +336,7 @@ GET /users/:user_id/projects
"forks_count": 0,
"star_count": 0,
"runners_token": "b8547b1dc37721d05889db52fa2f02",
+ "ci_default_git_depth": 50,
"public_jobs": true,
"shared_with_groups": [],
"only_allow_merge_if_pipeline_succeeds": false,
@@ -416,6 +419,7 @@ GET /users/:user_id/projects
"forks_count": 0,
"star_count": 0,
"runners_token": "b8547b1dc37721d05889db52fa2f02",
+ "ci_default_git_depth": 0,
"public_jobs": true,
"shared_with_groups": [],
"only_allow_merge_if_pipeline_succeeds": false,
@@ -528,6 +532,7 @@ GET /projects/:id
"forks_count": 0,
"star_count": 0,
"runners_token": "b8bc4a7a29eb76ea83cf79e4908c2b",
+ "ci_default_git_depth": 50,
"public_jobs": true,
"shared_with_groups": [
{
@@ -763,6 +768,7 @@ PUT /projects/:id
| `tag_list` | array | no | The list of tags for a project; put array of tags, that should be finally assigned to a project |
| `avatar` | mixed | no | Image file for avatar of the project |
| `ci_config_path` | string | no | The path to CI config file |
+| `ci_default_git_depth` | integer | no | Default number of revisions for [shallow cloning](../user/project/pipelines/settings.md#git-shallow-clone) |
## Fork project
@@ -1160,6 +1166,7 @@ Example response:
"forks_count": 0,
"star_count": 0,
"runners_token": "b8bc4a7a29eb76ea83cf79e4908c2b",
+ "ci_default_git_depth": 50,
"public_jobs": true,
"shared_with_groups": [],
"only_allow_merge_if_pipeline_succeeds": false,
@@ -1264,6 +1271,7 @@ Example response:
"forks_count": 0,
"star_count": 0,
"runners_token": "b8bc4a7a29eb76ea83cf79e4908c2b",
+ "ci_default_git_depth": 50,
"public_jobs": true,
"shared_with_groups": [],
"only_allow_merge_if_pipeline_succeeds": false,
diff --git a/doc/ci/README.md b/doc/ci/README.md
index 635cce13b4e..8b70699cdb5 100644
--- a/doc/ci/README.md
+++ b/doc/ci/README.md
@@ -32,6 +32,9 @@ your app.
For a complete overview of these methodologies and GitLab CI/CD,
read the [Introduction to CI/CD with GitLab](introduction/index.md).
+<i class="fa fa-youtube-play youtube" aria-hidden="true"></i>
+For a video demonstration of GitLab CI/CD, see [Demo: CI/CD with GitLab](https://www.youtube.com/watch?v=1iXFbchozdY).
+
## Getting started
GitLab CI/CD is configured by a file called `.gitlab-ci.yml` placed
@@ -124,12 +127,10 @@ Its feature set is listed on the table below according to DevOps stages.
## Examples
-GitLab provides examples of configuring GitLab CI/CD in the form of:
+Find example project code and tutorials for using GitLab CI/CD with a variety of app frameworks, languages, and platforms
+on the [CI Examples](examples/README.md) page.
-- A collection of [examples and other resources](examples/README.md).
-- Example projects that are available at the [`gitlab-examples`](https://gitlab.com/gitlab-examples) group. For example, see:
- - [`multi-project-pipelines`](https://gitlab.com/gitlab-examples/multi-project-pipelines) for examples of implementing multi-project pipelines.
- - [`review-apps-nginx`](https://gitlab.com/gitlab-examples/review-apps-nginx/) provides an example of using Review Apps.
+GitLab also provides [example projects](https://gitlab.com/gitlab-examples) pre-configured to use GitLab CI/CD.
## Administration **[CORE ONLY]**
diff --git a/doc/ci/ci_cd_for_external_repos/github_integration.md b/doc/ci/ci_cd_for_external_repos/github_integration.md
index 612dcc93bc1..2a8ddb610f9 100644
--- a/doc/ci/ci_cd_for_external_repos/github_integration.md
+++ b/doc/ci/ci_cd_for_external_repos/github_integration.md
@@ -5,24 +5,17 @@ type: howto
# Using GitLab CI/CD with a GitHub repository **[PREMIUM]**
GitLab CI/CD can be used with **GitHub.com** and **GitHub Enterprise** by
-creating a [CI/CD project](https://docs.gitlab.com/ee/user/project/ci_cd_for_external_repo.html) to connect your GitHub repository to
+creating a [CI/CD project](index.md) to connect your GitHub repository to
GitLab.
-NOTE: **Note:**
-To use **GitHub Enterprise** with **GitLab.com** you should use the
-manual method.
+<i class="fa fa-youtube-play youtube" aria-hidden="true"></i>
+Watch a video on [Using GitLab CI/CD pipelines with GitHub repositories](https://www.youtube.com/watch?v=qgl3F2j-1cI).
## Connect with GitHub integration
If the [GitHub integration](../../integration/github.md) has been enabled by your GitLab
administrator:
-NOTE: **Note:**
-Due to a 10-token limitation on the [GitHub OAuth Implementation](https://developer.github.com/apps/building-oauth-apps/authorizing-oauth-apps/#creating-multiple-tokens-for-oauth-apps),
-if you import more than 10 times, your oldest imported project's token will be
-revoked. See issue [#9147](https://gitlab.com/gitlab-org/gitlab-ee/issues/9147)
-for more information.
-
1. In GitLab create a **CI/CD for external repo** project and select
**GitHub**.
@@ -42,6 +35,12 @@ GitLab will:
1. Enable [GitHub project integration](https://docs.gitlab.com/ee/user/project/integrations/github.html).
1. Create a web hook on GitHub to notify GitLab of new commits.
+CAUTION: **Caution:**
+Due to a 10-token limitation on the [GitHub OAuth Implementation](https://developer.github.com/apps/building-oauth-apps/authorizing-oauth-apps/#creating-multiple-tokens-for-oauth-apps),
+if you import more than 10 times, your oldest imported project's token will be
+revoked. See issue [#9147](https://gitlab.com/gitlab-org/gitlab-ee/issues/9147)
+for more information.
+
## Connect with Personal Access Token
NOTE: **Note:**
@@ -79,6 +78,9 @@ GitLab will:
## Connect manually
+NOTE: **Note:**
+To use **GitHub Enterprise** with **GitLab.com** use this method.
+
If the [GitHub integration](../../integration/github.md) is not enabled, or is enabled
for a different GitHub instance, you GitLab CI/CD can be manually enabled for
your repository:
diff --git a/doc/ci/ci_cd_for_external_repos/index.md b/doc/ci/ci_cd_for_external_repos/index.md
index 5de88412121..d46e451c609 100644
--- a/doc/ci/ci_cd_for_external_repos/index.md
+++ b/doc/ci/ci_cd_for_external_repos/index.md
@@ -4,12 +4,12 @@ type: index, howto
# GitLab CI/CD for external repositories **[PREMIUM]**
+>[Introduced][ee-4642] in [GitLab Premium][eep] 10.6.
+
NOTE: **Note:**
This feature [is available for free](https://about.gitlab.com/2019/03/21/six-more-months-ci-cd-github/) to
GitLab.com users until September 22nd, 2019.
->[Introduced][ee-4642] in [GitLab Premium][eep] 10.6.
-
GitLab CI/CD can be used with:
- [GitHub](github_integration.md).
diff --git a/doc/ci/docker/using_docker_build.md b/doc/ci/docker/using_docker_build.md
index d8068bbb7f0..b4c4bea6447 100644
--- a/doc/ci/docker/using_docker_build.md
+++ b/doc/ci/docker/using_docker_build.md
@@ -90,7 +90,7 @@ The second approach is to use the special docker-in-docker (dind)
(`docker`) and run the job script in context of that
image in privileged mode.
-NOTE: **Note:** `docker-compose` is not part of docker-in-docker (dind). In case you'd like to use `docker-compose` in your CI builds, please follow the (installation instructions for docker-compose)[https://docs.docker.com/compose/install/] provided by docker.
+NOTE: **Note:** `docker-compose` is not part of docker-in-docker (dind). In case you'd like to use `docker-compose` in your CI builds, please follow the [installation instructions for docker-compose](https://docs.docker.com/compose/install/) provided by docker.
In order to do that, follow the steps:
diff --git a/doc/ci/docker/using_docker_images.md b/doc/ci/docker/using_docker_images.md
index d09efce7cc1..29578efacbb 100644
--- a/doc/ci/docker/using_docker_images.md
+++ b/doc/ci/docker/using_docker_images.md
@@ -466,6 +466,29 @@ that runner.
> - If the repository is private you need to authenticate your GitLab Runner in the
> registry. Learn more about how [GitLab Runner works in this case][runner-priv-reg].
+To access private container registries, the GitLab Runner process can use:
+
+- [Statically defined credentials](#using-statically-defined-credentials). That is, a username and password for a specific registry.
+- [Credentials Store](#using-credentials-store). For more information, see [the relevant Docker documentation](https://docs.docker.com/engine/reference/commandline/login/#credentials-store).
+- [Credential Helpers](#using-credential-helpers). For more information, see [the relevant Docker documentation](https://docs.docker.com/engine/reference/commandline/login/#credential-helpers).
+
+To define which should be used, the GitLab Runner process reads the configuration in the following order:
+
+- `DOCKER_AUTH_CONFIG` variable provided as either:
+ - A [variable](../variables/README.md#gitlab-cicd-environment-variables) in `.gitlab-ci.yml`.
+ - A project's variables stored on the projects **Settings > CI/CD** page.
+- `DOCKER_AUTH_CONFIG` variable provided as environment variable in `config.toml` of the Runner.
+- `config.json` file placed in `$HOME/docker` directory of the user running GitLab Runner process.
+ If the `--user` flag is provided to run the GitLab Runner child processes as unprivileged user,
+ the home directory of the main GitLab Runner process user will be used.
+
+NOTE: **Note:**
+GitLab Runner reads this configuration **only** from `config.toml` and ignores it if
+it's provided as an environment variable. This is because GitLab Runnner uses **only**
+`config.toml` configuration and doesn't interpolate **ANY** environment variables at
+runtime.
+
+### Using statically-defined credentials
As an example, let's assume that you want to use the `registry.example.com:5000/private/image:latest`
image which is private and requires you to login into a private container registry.
@@ -543,6 +566,78 @@ for the Runner to match the `DOCKER_AUTH_CONFIG`. For example, if
then the `DOCKER_AUTH_CONFIG` must also specify `registry.example.com:5000`.
Specifying only `registry.example.com` will not work.
+
+### Using Credentials Store
+
+> Support for using Credentials Store was added in GitLab Runner 9.5.
+
+To configure credentials store, follow these steps:
+
+1. To use a credentials store, you need an external helper program to interact with a specific keychain or external store.
+Make sure helper program is available in GitLab Runner `$PATH`.
+
+1. Make GitLab Runner use it. There are two ways to accomplish this. Either:
+ - Create a
+ [variable](../variables/README.md#gitlab-cicd-environment-variables)
+ `DOCKER_AUTH_CONFIG` with the content of the
+ Docker configuration file as the value:
+
+ ```json
+ {
+ "credsStore": "osxkeychain"
+ }
+ ```
+
+ - Or, if you are running self-hosted Runners, add the above JSON to
+ `${GITLAB_RUNNER_HOME}/.docker/config.json`. GitLab Runner will read this config file
+ and will use the needed helper for this specific repository.
+
+NOTE: **Note:** `credsStore` is used to access ALL the registries.
+If you will want to use both images from private registry and public images from DockerHub,
+pulling from DockerHub will fail, because Docker daemon will try to use the same credentials for **ALL** the registries.
+
+### Using Credential Helpers
+
+> Support for using Credential Helpers was added in GitLab Runner 12.0
+
+As an example, let's assume that you want to use the `aws_account_id.dkr.ecr.region.amazonaws.com/private/image:latest`
+image which is private and requires you to log in into a private container registry.
+
+To configure access for `aws_account_id.dkr.ecr.region.amazonaws.com`, follow these steps:
+
+1. Make sure `docker-credential-ecr-login` is available in GitLab Runner's `$PATH`.
+
+1. Make GitLab Runner use it. There are two ways to accomplish this. Either:
+ - Create a [variable](../variables/README.md#gitlab-cicd-environment-variables)
+ `DOCKER_AUTH_CONFIG` with the content of the
+ Docker configuration file as the value:
+
+ ```json
+ {
+ "credHelpers": {
+ "aws_account_id.dkr.ecr.region.amazonaws.com": "ecr-login"
+ }
+ }
+ ```
+
+ - Or, if you are running self-hosted Runners,
+ add the above JSON to `${GITLAB_RUNNER_HOME}/.docker/config.json`.
+ GitLab Runner will read this config file and will use the needed helper for this
+ specific repository.
+
+1. You can now use any private image from `aws_account_id.dkr.ecr.region.amazonaws.com` defined in
+ `image` and/or `services` in your `.gitlab-ci.yml` file:
+
+ ```yaml
+ image: aws_account_id.dkr.ecr.region.amazonaws.com/private/image:latest
+ ```
+
+ In the example above, GitLab Runner will look at `aws_account_id.dkr.ecr.region.amazonaws.com` for the
+ image `private/image:latest`.
+
+You can add configuration for as many registries as you want, adding more
+registries to the `"credHelpers"` hash as described above.
+
## Configuring services
Many services accept environment variables which allow you to easily change
diff --git a/doc/ci/environments.md b/doc/ci/environments.md
index f2661c4bafd..bd419965a9c 100644
--- a/doc/ci/environments.md
+++ b/doc/ci/environments.md
@@ -617,6 +617,10 @@ versions of the app, all without leaving GitLab.
![Monitoring dashboard](img/environments_monitoring.png)
+#### Linking to external dashboard
+
+Add a [button to the Monitoring dashboard](../user/project/operations/linking_to_an_external_dashboard.md) linking directly to your existing external dashboards.
+
### Web terminals
> Web terminals were added in GitLab 8.15 and are only available to project Maintainers and Owners.
diff --git a/doc/ci/examples/README.md b/doc/ci/examples/README.md
index 340a41c196b..1548b0e619f 100644
--- a/doc/ci/examples/README.md
+++ b/doc/ci/examples/README.md
@@ -1,47 +1,42 @@
---
comments: false
+type: index
---
# GitLab CI/CD Examples
-Examples are a useful way of understanding how to implement GitLab CI/CD for your specific use case.
+This page contains links to a variety of examples that can help you understand how to
+implement [GitLab CI/CD](../README.md) for your specific use case.
Examples are available in several forms. As a collection of:
- `.gitlab-ci.yml` [template files](https://gitlab.com/gitlab-org/gitlab-ce/tree/master/lib/gitlab/ci/templates) maintained in GitLab. When you create a new file via the UI,
GitLab will give you the option to choose one of these templates. This will allow you to quickly bootstrap your project for CI/CD.
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.
-- Repositories with [example projects](https://gitlab.com/gitlab-examples) for various languages. You can fork and adjust them to your own needs.
+- Repositories with [example projects](https://gitlab.com/gitlab-examples) for various languages. You can fork and adjust them to your own needs. Projects include demonstrations of [multi-project pipelines](https://gitlab.com/gitlab-examples/multi-project-pipelines) and using [Review Apps with a static site served by nginx](https://gitlab.com/gitlab-examples/review-apps-nginx/).
- Examples and [other resources](#other-resources) listed below.
## CI/CD examples
-The following table lists examples for different use cases:
-
-| Use case | Resource |
-|:-----------------------------------------------|:------------------------------------------------------------------------------------------------------------------------|
-| Browser performance testing | [Browser Performance Testing with the Sitespeed.io container](browser_performance.md). |
-| Clojure | [Test a Clojure application with GitLab CI/CD](test-clojure-application.md). |
-| Code quality analysis | [Analyze your project's Code Quality](code_quality.md). **[STARTER]** |
-| Container scanning | [Container Scanning with GitLab CI/CD](../../user/application_security/container_scanning/index.md). **[ULTIMATE]** |
-| Dependency scanning | [Dependency Scanning with GitLab CI/CD](../../user/application_security/dependency_scanning/index.md). **[ULTIMATE]** |
-| Deployment with `dpl` | [Using `dpl` as deployment tool](deployment/README.md). |
-| Dynamic application<br>security testing (DAST) | [Dynamic Application Security Testing with GitLab CI/CD](../../user/application_security/dast/index.md). **[ULTIMATE]** |
-| Elixir | [Testing a Phoenix application with GitLab CI/CD](test_phoenix_app_with_gitlab_ci_cd/index.md). |
-| Game development | [DevOps and Game Dev with GitLab CI/CD](devops_and_game_dev_with_gitlab_ci_cd/index.md). |
-| GitLab Pages | See the [GitLab Pages](../../user/project/pages/index.md) documentation for a complete example. |
-| Java | [Deploy a Spring Boot application to Cloud Foundry with GitLab CI/CD](deploy_spring_boot_to_cloud_foundry/index.md). |
-| JUnit | [JUnit test reports](../junit_test_reports.md). |
-| License management | [Dependencies license management with GitLab CI/CD](../../user/application_security/license_management/index.md). **[ULTIMATE]** |
-| Maven | [How to deploy Maven projects to Artifactory with GitLab CI/CD](artifactory_and_gitlab/index.md). |
-| PHP | [Testing PHP projects](php.md). |
-| PHP | [Running Composer and NPM scripts with deployment via SCP in GitLab CI/CD](deployment/composer-npm-deploy.md). |
-| PHP | [Test and deploy Laravel applications with GitLab CI/CD and Envoy](laravel_with_gitlab_and_envoy/index.md). |
-| Python | [Test and deploy a Python application with GitLab CI/CD](test-and-deploy-python-application-to-heroku.md). |
-| Ruby | [Test and deploy a Ruby application with GitLab CI/CD](test-and-deploy-ruby-application-to-heroku.md). |
-| Scala | [Test and deploy a Scala application to Heroku](test-scala-application.md). |
-| Static application<br>security testing (SAST) | [Static Application Security Testing with GitLab CI/CD](../../user/application_security/sast/index.md). **[ULTIMATE]** |
-| Testing | [End-to-end testing with GitLab CI/CD and WebdriverIO](end_to_end_testing_webdriverio/index.md). |
+The following table lists examples with step-by-step tutorials that are contained in this section.
+
+| Use case | Resource |
+|:----------------------------|:---------------------------------------------------------------------------------------------------------------------------|
+| Browser performance testing | [Browser Performance Testing with the Sitespeed.io container](browser_performance.md). |
+| Clojure | [Test a Clojure application with GitLab CI/CD](test-clojure-application.md). |
+| Deployment with Dpl | [Using `dpl` as deployment tool](deployment/README.md). |
+| Elixir | [Testing a Phoenix application with GitLab CI/CD](test_phoenix_app_with_gitlab_ci_cd/index.md). |
+| End-to-end testing | [End-to-end testing with GitLab CI/CD and WebdriverIO](end_to_end_testing_webdriverio/index.md). |
+| Game development | [DevOps and Game Dev with GitLab CI/CD](devops_and_game_dev_with_gitlab_ci_cd/index.md). |
+| GitLab Pages | See the [GitLab Pages](../../user/project/pages/index.md) documentation for a complete example of deploying a static site. |
+| Java with Spring Boot | [Deploy a Spring Boot application to Cloud Foundry with GitLab CI/CD](deploy_spring_boot_to_cloud_foundry/index.md). |
+| Java with Maven | [How to deploy Maven projects to Artifactory with GitLab CI/CD](artifactory_and_gitlab/index.md). |
+| PHP with PHPunit, atoum | [Testing PHP projects](php.md). |
+| PHP with NPM, SCP | [Running Composer and NPM scripts with deployment via SCP in GitLab CI/CD](deployment/composer-npm-deploy.md). |
+| PHP with Laravel, Ennvoy | [Test and deploy Laravel applications with GitLab CI/CD and Envoy](laravel_with_gitlab_and_envoy/index.md). |
+| Python on Heroku | [Test and deploy a Python application with GitLab CI/CD](test-and-deploy-python-application-to-heroku.md). |
+| Ruby on Heroku | [Test and deploy a Ruby application with GitLab CI/CD](test-and-deploy-ruby-application-to-heroku.md). |
+| Scala on Heroku | [Test and deploy a Scala application to Heroku](test-scala-application.md). |
### Contributing examples
@@ -50,24 +45,29 @@ 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.
-### Adding templates to your GitLab installation **[PREMIUM ONLY]**
+## Adding templates to your GitLab installation **[PREMIUM ONLY]**
If you want to have customized examples and templates for your own self-managed GitLab instance available to your team, your GitLab administrator can [designate an instance template repository](https://docs.gitlab.com/ee/user/admin_area/settings/instance_template_repository.html) that contains examples and templates specific to your enterprise.
## Other resources
-This section provides further resources to help you get familiar with different aspects of GitLab CI/CD.
-
-NOTE: **Note:**
-These resources may no longer reflect the current state of GitLab CI/CD.
+This section provides further resources to help you get familiar with various uses of GitLab CI/CD.
+Note that older articles and videos may not reflect the state of the latest GitLab release.
### CI/CD in the cloud
For examples of setting up GitLab CI/CD for cloud-based environments, see:
- [How to set up multi-account AWS SAM deployments with GitLab CI](https://about.gitlab.com/2019/02/04/multi-account-aws-sam-deployments-with-gitlab-ci/)
+- [Automating Kubernetes Deployments with GitLab CI/CD](https://www.youtube.com/watch?v=wEDRfAz6_Uw)
- [How to autoscale continuous deployment with GitLab Runner on DigitalOcean](https://about.gitlab.com/2018/06/19/autoscale-continuous-deployment-gitlab-runner-digital-ocean/)
- [How to create a CI/CD pipeline with Auto Deploy to Kubernetes using GitLab and Helm](https://about.gitlab.com/2017/09/21/how-to-create-ci-cd-pipeline-with-autodeploy-to-kubernetes-using-gitlab-and-helm/)
+- [Demo - Deploying from GitLab to OpenShift Container Cluster](https://youtu.be/EwbhA53Jpp4)
+
+See also the following video overviews:
+
+- [Containers, Schedulers, and GitLab CI](https://www.youtube.com/watch?v=d-9awBxEbvQ).
+- [Deploying to IBM Cloud with GitLab CI/CD](https://www.youtube.com/watch?v=6ZF4vgKMd-g).
### Customer stories
@@ -83,7 +83,6 @@ For some examples to help get you started, see:
- [GitLab CI/CD's 2018 highlights](https://about.gitlab.com/2019/01/21/gitlab-ci-cd-features-improvements/)
- [A beginner's guide to continuous integration](https://about.gitlab.com/2018/01/22/a-beginners-guide-to-continuous-integration/)
-- [Making CI easier with GitLab](https://about.gitlab.com/2017/07/13/making-ci-easier-with-gitlab/)
### Implementing GitLab CI/CD
@@ -101,6 +100,10 @@ For examples of others who have implemented GitLab CI/CD, see:
- [Fast and natural continuous integration with GitLab CI](https://about.gitlab.com/2017/05/22/fast-and-natural-continuous-integration-with-gitlab-ci/)
- [Demo: CI/CD with GitLab in action](https://about.gitlab.com/2017/03/13/ci-cd-demo/)
+### Migrating to GitLab from third-party CI tools
+
+- [Migrating from Jenkins to GitLab](https://youtu.be/RlEVGOpYF5Y)
+
### Integrating GitLab CI/CD with other systems
To see how you can integrate GitLab CI/CD with third-party systems, see:
diff --git a/doc/ci/examples/artifactory_and_gitlab/index.md b/doc/ci/examples/artifactory_and_gitlab/index.md
index 589912e7a2a..e85a13f2187 100644
--- a/doc/ci/examples/artifactory_and_gitlab/index.md
+++ b/doc/ci/examples/artifactory_and_gitlab/index.md
@@ -4,6 +4,7 @@ author: Fabio Busatto
author_gitlab: bikebilly
level: intermediate
article_type: tutorial
+type: tutorial
date: 2017-08-15
---
@@ -16,8 +17,8 @@ to build a [Maven](https://maven.apache.org/) project, deploy it to [Artifactory
You'll create two different projects:
-- `simple-maven-dep`: the app built and deployed to Artifactory (available at <https://gitlab.com/gitlab-examples/maven/simple-maven-dep>)
-- `simple-maven-app`: the app using the previous one as a dependency (available at <https://gitlab.com/gitlab-examples/maven/simple-maven-app>)
+- `simple-maven-dep`: the app built and deployed to Artifactory (see the [simple-maven-dep](https://gitlab.com/gitlab-examples/maven/simple-maven-dep) example project)
+- `simple-maven-app`: the app using the previous one as a dependency (see the [simple-maven-app](https://gitlab.com/gitlab-examples/maven/simple-maven-app) example project)
We assume that you already have a GitLab account on [GitLab.com](https://gitlab.com/), and that you know the basic usage of Git and [GitLab CI/CD](https://about.gitlab.com/product/continuous-integration/).
We also assume that an Artifactory instance is available and reachable from the internet, and that you have valid credentials to deploy on it.
diff --git a/doc/ci/examples/browser_performance.md b/doc/ci/examples/browser_performance.md
index 442d0788d37..4c42811edf4 100644
--- a/doc/ci/examples/browser_performance.md
+++ b/doc/ci/examples/browser_performance.md
@@ -1,13 +1,17 @@
-# Browser Performance Testing with the Sitespeed.io container
+---
+type: howto
+---
-CAUTION: **Caution:**
+# Browser Performance Testing with the sitespeed.io container
+
+NOTE: **Note:**
The job definition shown below is supported on GitLab 11.5 and later versions.
It also requires the GitLab Runner 11.5 or later.
For earlier versions, use the [previous job definitions](#previous-job-definitions).
This example shows how to run the
-[Sitespeed.io container](https://hub.docker.com/r/sitespeedio/sitespeed.io/) on
-your code by using GitLab CI/CD and [Sitespeed.io](https://www.sitespeed.io)
+[sitespeed.io container](https://hub.docker.com/r/sitespeedio/sitespeed.io/) on
+your code by using GitLab CI/CD and [sitespeed.io](https://www.sitespeed.io)
using Docker-in-Docker.
First, you need GitLab Runner with
@@ -38,20 +42,20 @@ performance:
```
The above example will create a `performance` job in your CI/CD pipeline and will run
-Sitespeed.io against the webpage you defined in `URL` to gather key metrics.
+sitespeed.io against the webpage you defined in `URL` to gather key metrics.
The [GitLab plugin](https://gitlab.com/gitlab-org/gl-performance) for
-Sitespeed.io is downloaded in order to save the report as a
+sitespeed.io is downloaded in order to save the report as a
[Performance report artifact](../yaml/README.md#artifactsreportsperformance-premium)
that you can later download and analyze.
Due to implementation limitations we always take the latest Performance artifact available.
-The full HTML Sitespeed.io report will also be saved as an artifact, and if you have
+The full HTML sitespeed.io report will also be saved as an artifact, and if you have
[GitLab Pages](../../user/project/pages/index.md) enabled, it can be viewed
directly in your browser.
-For further customization options of Sitespeed.io, including the ability to
-provide a list of URLs to test, please consult
-[their documentation](https://www.sitespeed.io/documentation/sitespeed.io/configuration/).
+For further customization options for sitespeed.io, including the ability to
+provide a list of URLs to test, please see the
+[Sitespeed.io Configuration](https://www.sitespeed.io/documentation/sitespeed.io/configuration/) documentation.
TIP: **Tip:**
For [GitLab Premium](https://about.gitlab.com/pricing/) users, key metrics are automatically
@@ -73,7 +77,7 @@ set this up:
1. In the `performance` job, read the previous artifact into an environment
variable, like `$CI_ENVIRONMENT_URL`, and use it to parameterize the test
URLs.
-1. You can now run the Sitespeed.io container against the desired hostname and
+1. You can now run the sitespeed.io container against the desired hostname and
paths.
Your `.gitlab-ci.yml` file would look like:
diff --git a/doc/ci/examples/code_quality.md b/doc/ci/examples/code_quality.md
index 186d4527bb6..4a9bfa51528 100644
--- a/doc/ci/examples/code_quality.md
+++ b/doc/ci/examples/code_quality.md
@@ -1,3 +1,7 @@
+---
+type: reference, howto
+---
+
# Analyze your project's Code Quality
CAUTION: **Caution:**
diff --git a/doc/ci/examples/deploy_spring_boot_to_cloud_foundry/index.md b/doc/ci/examples/deploy_spring_boot_to_cloud_foundry/index.md
index c622dd86828..538843ab8dc 100644
--- a/doc/ci/examples/deploy_spring_boot_to_cloud_foundry/index.md
+++ b/doc/ci/examples/deploy_spring_boot_to_cloud_foundry/index.md
@@ -3,6 +3,7 @@ author: Dylan Griffith
author_gitlab: DylanGriffith
level: intermediate
article_type: tutorial
+type: tutorial
date: 2018-06-07
last_updated: 2019-04-08
description: "Continuous Deployment of a Spring Boot application to Cloud Foundry with GitLab CI/CD"
@@ -26,13 +27,13 @@ using GitLab CI/CD, read through the blog post [Continuous Delivery of a Spring
## Requirements
-_We assume you are familiar with Java, GitLab, Cloud Foundry, and GitLab CI/CD._
+This tutorial assumes you are familiar with Java, GitLab, Cloud Foundry, and GitLab CI/CD.
-To follow along with this tutorial you will need the following:
+To follow along, you will need:
- An account on [Pivotal Web Services (PWS)](https://run.pivotal.io/) or any
- other Cloud Foundry instance
-- An account on GitLab
+ other Cloud Foundry (CF) instance.
+- An account on GitLab.
NOTE: **Note:**
You will need to replace the `api.run.pivotal.io` URL in the all below
diff --git a/doc/ci/examples/deployment/README.md b/doc/ci/examples/deployment/README.md
index 010ba6b66a2..26b10c7eeaf 100644
--- a/doc/ci/examples/deployment/README.md
+++ b/doc/ci/examples/deployment/README.md
@@ -1,12 +1,14 @@
+---
+type: tutorial
+---
+
# Using Dpl as deployment tool
-[Dpl](https://github.com/travis-ci/dpl) (dee-pee-ell) is a deploy tool made for
+[Dpl](https://github.com/travis-ci/dpl) (prouncounced like the letters D-P-L) is a deploy tool made for
continuous deployment that's developed and used by Travis CI, but can also be
used with GitLab CI.
->**Note:**
-We recommend to use Dpl if you're deploying to any of these services:
-<https://github.com/travis-ci/dpl#supported-providers>.
+Dpl can be used to deploy to any of the [supported providers](https://github.com/travis-ci/dpl#supported-providers).
## Requirements
@@ -50,8 +52,8 @@ To use different provider take a look at long list of [Supported Providers](http
## Using Dpl with Docker
-When you use GitLab Runner you most likely configured it to use your server's shell commands.
-This means that all commands are run in context of local user (ie. gitlab_runner or gitlab_ci_multi_runner).
+In most cases, you will have configured [GitLab Runner](https://docs.gitlab.com/runner/) to use your server's shell commands.
+This means that all commands are run in the context of local user (e.g. gitlab_runner or gitlab_ci_multi_runner).
It also means that most probably in your Docker container you don't have the Ruby runtime installed.
You will have to install it:
diff --git a/doc/ci/examples/deployment/composer-npm-deploy.md b/doc/ci/examples/deployment/composer-npm-deploy.md
index 4758ccad5aa..79b3cbd0c69 100644
--- a/doc/ci/examples/deployment/composer-npm-deploy.md
+++ b/doc/ci/examples/deployment/composer-npm-deploy.md
@@ -1,8 +1,12 @@
+---
+type: tutorial
+---
+
# Running Composer and NPM scripts with deployment via SCP in GitLab CI/CD
-This guide covers the building dependencies of a PHP project while compiling assets via an NPM script.
+This guide covers the building of dependencies of a PHP project while compiling assets via an NPM script using [GitLab CI/CD](../../README.md).
-While is possible to create your own image with custom PHP and Node JS versions, for brevity, we will use an existing [Docker image](https://hub.docker.com/r/tetraweb/php/) that contains both PHP and NodeJS installed.
+While it is possible to create your own image with custom PHP and Node JS versions, for brevity, we will use an existing [Docker image](https://hub.docker.com/r/tetraweb/php/) that contains both PHP and NodeJS installed.
```yaml
image: tetraweb/php
@@ -46,9 +50,9 @@ To make this work, you need to add a GitLab CI/CD Variable (accessible on _gitla
### Security tip
-Create a user that has access **only** to the folder that needs to be updated!
+Create a user that has access **only** to the folder that needs to be updated.
-After you create that variable, you need to make sure that key will be added to the docker container on run:
+After you create that variable, you need to make sure that key will be added to the Docker container on run:
```yaml
before_script:
@@ -68,7 +72,7 @@ In order, this means that:
And this is basically all you need in the `before_script` section.
-## How to deploy things
+## How to deploy
As we stated above, we need to deploy the `build` folder from the docker image to our server. To do so, we create a new job:
@@ -93,7 +97,7 @@ Here's the breakdown:
1. `ssh-add ...` we will add that private key you added on the web UI to the docker container
1. We will connect via `ssh` and create a new `_tmp` folder
1. We will connect via `scp` and upload the `build` folder (which was generated by a `npm` script) to our previously created `_tmp` folder
-1. We will connect again to `ssh` and move the `live` folder to an `_old` folder, then move `_tmp` to `live`.
+1. We will connect again via `ssh` and move the `live` folder to an `_old` folder, then move `_tmp` to `live`.
1. We connect to ssh and remove the `_old` folder
What's the deal with the artifacts? We just tell GitLab CI to keep the `build` directory (later on, you can download that as needed).
@@ -109,14 +113,14 @@ If you're using this only for stage server, you could do this in two steps:
The problem is that there will be a small period of time when you won't have the app on your server.
-So we use so many steps because we want to make sure that at any given time we have a functional app in place.
+Therefore, for a production environment we use additional steps to ensure that at any given time, a functional app is in place.
## Where to go next
-Since this was a WordPress project, I gave real life code snippets. Some ideas you can pursuit:
+Since this was a WordPress project, I gave real life code snippets. Some further ideas you can pursue:
-- Having a slightly different script for `master` branch will allow you to deploy to a production server from that branch and to a stage server from any other branches;
-- Instead of pushing it live, you can push it to WordPress official repo (with creating a SVN commit & stuff);
+- Having a slightly different script for `master` branch will allow you to deploy to a production server from that branch and to a stage server from any other branches.
+- Instead of pushing it live, you can push it to WordPress official repo (with creating a SVN commit, etc.).
- You could generate i18n text domains on the fly.
---
diff --git a/doc/ci/examples/devops_and_game_dev_with_gitlab_ci_cd/index.md b/doc/ci/examples/devops_and_game_dev_with_gitlab_ci_cd/index.md
index d6ad00a77da..50e61cafeb9 100644
--- a/doc/ci/examples/devops_and_game_dev_with_gitlab_ci_cd/index.md
+++ b/doc/ci/examples/devops_and_game_dev_with_gitlab_ci_cd/index.md
@@ -3,6 +3,7 @@ author: Ryan Hall
author_gitlab: blitzgren
level: intermediate
article_type: tutorial
+type: tutorial
date: 2018-03-07
last_updated: 2019-03-11
---
@@ -14,7 +15,7 @@ platforms without the use of plugins like Adobe Flash. Furthermore, by using Git
single game developers, as well as game dev teams, can easily host browser-based games online.
In this tutorial, we'll focus on DevOps, as well as testing and hosting games with Continuous
-Integration/Deployment methods. We assume you are familiar with GitLab, javascript,
+Integration/Deployment methods using [GitLab CI/CD](../../README.md). We assume you are familiar with GitLab, JavaScript,
and the basics of game development.
## The game
diff --git a/doc/ci/examples/end_to_end_testing_webdriverio/index.md b/doc/ci/examples/end_to_end_testing_webdriverio/index.md
index bd221b7145e..7f1beb96bbf 100644
--- a/doc/ci/examples/end_to_end_testing_webdriverio/index.md
+++ b/doc/ci/examples/end_to_end_testing_webdriverio/index.md
@@ -3,6 +3,7 @@ author: Vincent Tunru
author_gitlab: Vinnl
level: advanced
article_type: user guide
+type: tutorial
date: 2019-02-18
description: 'Confidence checking your entire app every time a new feature is added can quickly become repetitive. Learn how to automate it with GitLab CI/CD.'
---
@@ -22,7 +23,9 @@ However, looking at the freshly deployed code to check whether it still looks an
expected is repetitive manual work, which means it is a prime candidate for automation. This is
where automated [end-to-end testing](https://martinfowler.com/bliki/BroadStackTest.html) comes in:
having the computer run through a few simple scenarios that requires the proper functioning of all
-layers of your application, from the frontend to the database. In this article, we will discuss how
+layers of your application, from the frontend to the database.
+
+In this article, we will discuss how
to write such end-to-end tests, and how to set up GitLab CI/CD to automatically run these tests
against your new code, on a branch-by-branch basis. For the scope of this article, we will walk you
through the process of setting up GitLab CI/CD for end-to-end testing Javascript-based applications
diff --git a/doc/ci/examples/laravel_with_gitlab_and_envoy/index.md b/doc/ci/examples/laravel_with_gitlab_and_envoy/index.md
index f56d5429fb7..d7308a3a5ec 100644
--- a/doc/ci/examples/laravel_with_gitlab_and_envoy/index.md
+++ b/doc/ci/examples/laravel_with_gitlab_and_envoy/index.md
@@ -4,6 +4,7 @@ author: Mehran Rasulian
author_gitlab: mehranrasulian
level: intermediate
article_type: tutorial
+type: tutorial
date: 2017-08-31
last_updated: 2019-03-06
---
diff --git a/doc/ci/examples/php.md b/doc/ci/examples/php.md
index c1048f3d2e3..c459bb7001f 100644
--- a/doc/ci/examples/php.md
+++ b/doc/ci/examples/php.md
@@ -1,8 +1,12 @@
+---
+type: tutorial
+---
+
# Testing PHP projects
This guide covers basic building instructions for PHP projects.
-There are covered two cases: testing using the Docker executor and testing
+Two testing scenarios are covered: using the Docker executor and
using the Shell executor.
## Test PHP projects using the Docker executor
@@ -245,7 +249,7 @@ before_script:
...
```
-## Access private packages / dependencies
+## Access private packages or dependencies
If your test suite needs to access a private repository, you need to configure
[the SSH keys](../ssh_keys/README.md) in order to be able to clone it.
@@ -254,7 +258,7 @@ If your test suite needs to access a private repository, you need to configure
Most of the time you will need a running database in order for your tests to
run. If you are using the Docker executor you can leverage Docker's ability to
-link to other containers. In GitLab Runner lingo, this can be achieved by
+link to other containers. With GitLab Runner, this can be achieved by
defining a `service`.
This functionality is covered in [the CI services](../services/README.md)
@@ -279,7 +283,7 @@ We have set up an [Example PHP Project][php-example-repo] for your convenience
that runs on [GitLab.com](https://gitlab.com) using our publicly available
[shared runners](../runners/README.md).
-Want to hack on it? Simply fork it, commit and push your changes. Within a few
+Want to hack on it? Simply fork it, commit, and push your changes. Within a few
moments the changes will be picked by a public runner and the job will begin.
[php-hub]: https://hub.docker.com/r/_/php/
diff --git a/doc/ci/examples/test-and-deploy-python-application-to-heroku.md b/doc/ci/examples/test-and-deploy-python-application-to-heroku.md
index 47d20a4e1c1..f9d185f187c 100644
--- a/doc/ci/examples/test-and-deploy-python-application-to-heroku.md
+++ b/doc/ci/examples/test-and-deploy-python-application-to-heroku.md
@@ -1,8 +1,12 @@
+---
+type: tutorial
+---
+
# Test and deploy a Python application with GitLab CI/CD
This example will guide you how to run tests in your Python application and deploy it automatically as Heroku application.
-You can checkout the [example source](https://gitlab.com/ayufan/python-getting-started).
+You can also view or fork the complete [example source](https://gitlab.com/ayufan/python-getting-started).
## Configure project
@@ -46,9 +50,9 @@ production:
This project has three jobs:
-- `test` - used to test Django application,
-- `staging` - used to automatically deploy staging environment every push to `master` branch
-- `production` - used to automatically deploy production environment for every created tag
+- `test` - used to test Django application.
+- `staging` - used to automatically deploy staging environment every push to `master` branch.
+- `production` - used to automatically deploy production environment for every created tag.
## Store API keys
@@ -67,8 +71,9 @@ You can do this through the [Dashboard](https://dashboard.heroku.com/).
## Create Runner
First install [Docker Engine](https://docs.docker.com/installation/).
+
To build this project you also need to have [GitLab Runner](https://docs.gitlab.com/runner).
-You can use public runners available on `gitlab.com`, but you can register your own:
+You can use public runners available on `gitlab.com` or you can register your own:
```sh
gitlab-runner register \
@@ -81,6 +86,6 @@ gitlab-runner register \
--docker-postgres latest
```
-With the command above, you create a runner that uses [python:3.5](https://hub.docker.com/r/_/python/) image and uses [postgres](https://hub.docker.com/r/_/postgres/) database.
+With the command above, you create a runner that uses the [python:3.5](https://hub.docker.com/r/_/python/) image and uses a [postgres](https://hub.docker.com/r/_/postgres/) database.
-To access PostgreSQL database you need to connect to `host: postgres` as user `postgres` without password.
+To access the PostgreSQL database, connect to `host: postgres` as user `postgres` with no password.
diff --git a/doc/ci/examples/test-and-deploy-ruby-application-to-heroku.md b/doc/ci/examples/test-and-deploy-ruby-application-to-heroku.md
index 3a0ddf001b8..79d54b52b5a 100644
--- a/doc/ci/examples/test-and-deploy-ruby-application-to-heroku.md
+++ b/doc/ci/examples/test-and-deploy-ruby-application-to-heroku.md
@@ -1,8 +1,12 @@
+---
+type: tutorial
+---
+
# Test and deploy a Ruby application with GitLab CI/CD
-This example will guide you how to run tests in your Ruby on Rails application and deploy it automatically as Heroku application.
+This example will guide you through how to run tests in your Ruby on Rails application and deploy it automatically as a Heroku application.
-You can checkout the example [source](https://gitlab.com/ayufan/ruby-getting-started) and check [CI status](https://gitlab.com/ayufan/ruby-getting-started/builds?scope=all).
+You can also view or fork the complete [example source](https://gitlab.com/ayufan/ruby-getting-started) and view the logs of its past [CI jobs](https://gitlab.com/ayufan/ruby-getting-started/-/jobs?scope=finished).
## Configure the project
@@ -53,13 +57,14 @@ Find your Heroku API key in [Manage Account](https://dashboard.heroku.com/accoun
## Create Heroku application
For each of your environments, you'll need to create a new Heroku application.
-You can do this through the [Dashboard](https://dashboard.heroku.com/).
+You can do this through the [Heroku Dashboard](https://dashboard.heroku.com/).
## Create Runner
First install [Docker Engine](https://docs.docker.com/installation/).
+
To build this project you also need to have [GitLab Runner](https://docs.gitlab.com/runner/).
-You can use public runners available on `gitlab.com`, but you can register your own:
+You can use public runners available on `gitlab.com` or register your own:
```sh
gitlab-runner register \
@@ -72,6 +77,6 @@ gitlab-runner register \
--docker-postgres latest
```
-With the command above, you create a Runner that uses [ruby:2.2](https://hub.docker.com/r/_/ruby/) image and uses [postgres](https://hub.docker.com/r/_/postgres/) database.
+With the command above, you create a Runner that uses the [ruby:2.2](https://hub.docker.com/r/_/ruby/) image and uses a [postgres](https://hub.docker.com/r/_/postgres/) database.
-To access PostgreSQL database you need to connect to `host: postgres` as user `postgres` without password.
+To access the PostgreSQL database, connect to `host: postgres` as user `postgres` with no password.
diff --git a/doc/ci/examples/test-clojure-application.md b/doc/ci/examples/test-clojure-application.md
index 3b1026d174f..5cda8702b56 100644
--- a/doc/ci/examples/test-clojure-application.md
+++ b/doc/ci/examples/test-clojure-application.md
@@ -1,8 +1,15 @@
+---
+type: tutorial
+---
+
+NOTE: **Note:**
+This document has not been updated recently and could be out of date. For the latest documentation, see the [GitLab CI/CD](../README.md) page and the [GitLab CI/CD Pipeline Configuration Reference](../yaml/README.md).
+
# Test a Clojure application with GitLab CI/CD
-This example will guide you how to run tests in your Clojure application.
+This example will guide you how to run tests on your Clojure application.
-You can checkout the example [source](https://gitlab.com/dzaporozhets/clojure-web-application) and check [CI status](https://gitlab.com/dzaporozhets/clojure-web-application/builds?scope=all).
+You can view or fork the [example source](https://gitlab.com/dzaporozhets/clojure-web-application) and view the logs of its past [CI jobs](https://gitlab.com/dzaporozhets/clojure-web-application/builds?scope=finished).
## Configure the project
@@ -28,8 +35,9 @@ test:
- lein test
```
-In before script we install JRE and [Leiningen](http://leiningen.org/).
-Sample project uses [migratus](https://github.com/yogthos/migratus) library to manage database migrations.
-So we added database migration as last step of `before_script` section
+In `before_script`, we install JRE and [Leiningen](http://leiningen.org/).
+
+The sample project uses the [migratus](https://github.com/yogthos/migratus) library to manage database migrations, and
+we have added a database migration as the last step of `before_script`.
-You can use public runners available on `gitlab.com` for testing your application with such configuration.
+You can use public runners available on `gitlab.com` for testing your application with this configuration.
diff --git a/doc/ci/examples/test-scala-application.md b/doc/ci/examples/test-scala-application.md
index e1164b8d03a..0e33a1ba060 100644
--- a/doc/ci/examples/test-scala-application.md
+++ b/doc/ci/examples/test-scala-application.md
@@ -1,9 +1,12 @@
+---
+type: tutorial
+---
+
# Test and deploy a Scala application to Heroku
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).
+applications using SBT. You can view or fork the [example project](https://gitlab.com/gitlab-examples/scala-sbt)
+and view the logs of its past [CI jobs](https://gitlab.com/gitlab-examples/scala-sbt/-/jobs?scope=finished).
## Add `.gitlab-ci.yml` file to project
@@ -41,12 +44,14 @@ deploy:
- dpl --provider=heroku --app=gitlab-play-sample-app --api-key=$HEROKU_API_KEY
```
-The `before_script` installs [SBT](http://www.scala-sbt.org/) and
-displays the version that is being used. The `test` stage executes SBT
-to compile and test the project.
-[scoverage](https://github.com/scoverage/sbt-scoverage) is used as an SBT
+In the above configuration:
+
+- The `before_script` installs [SBT](http://www.scala-sbt.org/) and
+displays the version that is being used.
+- The `test` stage executes SBT to compile and test the project.
+ - [sbt-scoverage](https://github.com/scoverage/sbt-scoverage) is used as an SBT
plugin to measure test coverage.
-The `deploy` stage automatically deploys the project to Heroku using dpl.
+- The `deploy` stage automatically deploys the project to Heroku using dpl.
You can use other versions of Scala and SBT by defining them in
`build.sbt`.
diff --git a/doc/ci/examples/test_phoenix_app_with_gitlab_ci_cd/index.md b/doc/ci/examples/test_phoenix_app_with_gitlab_ci_cd/index.md
index 4a5fda661df..ec25ca1bfc3 100644
--- a/doc/ci/examples/test_phoenix_app_with_gitlab_ci_cd/index.md
+++ b/doc/ci/examples/test_phoenix_app_with_gitlab_ci_cd/index.md
@@ -3,6 +3,7 @@ author: Alexandre S Hostert
author_gitlab: Hostert
level: beginner
article_type: tutorial
+type: tutorial
date: 2018-02-20
last_updated: 2019-03-06
---
@@ -16,11 +17,11 @@ simultaneous users.
That's why we're hearing so much about Phoenix today.
-In this tutorial, we'll teach you how to set up GitLab CI/CD to build and test a Phoenix
+In this tutorial, we'll teach you how to set up [GitLab CI/CD](../../README.md) to build and test a Phoenix
application.
-_We assume that you know how to create a Phoenix app, run tests locally, and how to work with Git
-and GitLab UI._
+The tutorial assumes that you know how to create a Phoenix app, run tests locally, and how to work with Git
+and the GitLab UI.
## Introduction
diff --git a/doc/ci/introduction/index.md b/doc/ci/introduction/index.md
index bd2b9b099f2..1687716df2e 100644
--- a/doc/ci/introduction/index.md
+++ b/doc/ci/introduction/index.md
@@ -205,6 +205,9 @@ With GitLab CI/CD you can also:
To see all CI/CD features, navigate back to the [CI/CD index](../README.md).
+<i class="fa fa-youtube-play youtube" aria-hidden="true"></i>
+Watch the video [GitLab CI Live Demo](https://www.youtube.com/watch?v=pBe4t1CD8Fc) with a deeper overview of GitLab CI/CD.
+
### Setting up GitLab CI/CD for the first time
To get started with GitLab CI/CD, you need to familiarize yourself
diff --git a/doc/ci/metrics_reports.md b/doc/ci/metrics_reports.md
index b7824402d45..3ded6673149 100644
--- a/doc/ci/metrics_reports.md
+++ b/doc/ci/metrics_reports.md
@@ -28,6 +28,11 @@ Consider the following examples of data that can utilize Metrics Reports:
Metrics are read from the metrics report (default: `metrics.txt`). They are parsed and displayed in the MR widget.
+All values are considered strings and string compare is used to find differences between the latest available `metrics` artifact from:
+
+- `master`
+- The feature branch
+
## How to set it up
Add a job that creates a [metrics report](yaml/README.md#artifactsreportsmetrics-premium) (default filename: `metrics.txt`). The file should conform to the [OpenMetrics](https://openmetrics.io/) format.
diff --git a/doc/development/architecture.md b/doc/development/architecture.md
index 650325121b2..5f32cd7eba2 100644
--- a/doc/development/architecture.md
+++ b/doc/development/architecture.md
@@ -1,3 +1,7 @@
+---
+table_display_block: true
+---
+
# GitLab Architecture Overview
## Software delivery
@@ -26,6 +30,21 @@ Gitaly executes git operations from gitlab-shell and the GitLab web app, and pro
You may also be interested in the [production architecture of GitLab.com](https://about.gitlab.com/handbook/engineering/infrastructure/production-architecture/).
+### Simplified Component Overview
+
+This is a simplified architecture diagram that can be used to
+understand GitLab's architecture.
+
+A complete architecture diagram is available in our
+[component diagram](#component-diagram) below.
+
+![Simplified Component Overview](img/architecture_simplified.png)
+
+<!--
+To update this diagram, GitLab team members can edit this source file:
+https://docs.google.com/drawings/d/1fBzAyklyveF-i-2q-OHUIqDkYfjjxC4mq5shwKSZHLs/edit.
+ -->
+
### Component diagram
```mermaid
@@ -121,7 +140,7 @@ Component statuses are linked to configuration documentation for each component.
| [PgBouncer](#pgbouncer) | Database connection pooling, failover | [⚙][pgbouncer-omnibus] | [❌][pgbouncer-charts] | [❌][pgbouncer-charts] | [✅](https://about.gitlab.com/handbook/engineering/infrastructure/production-architecture/#database-architecture) | ❌ | ❌ | EE Only |
| [Consul](#consul) | Database node discovery, failover | [⚙][consul-omnibus] | [❌][consul-charts] | [❌][consul-charts] | [✅](../user/gitlab_com/index.md#consul) | ❌ | ❌ | EE Only |
| [GitLab self-monitoring: Prometheus](#prometheus) | Time-series database, metrics collection, and query service | [✅][prometheus-omnibus] | [✅][prometheus-charts] | [⚙][prometheus-charts] | [✅](../user/gitlab_com/index.md#prometheus) | ❌ | ❌ | CE & EE |
-| [GitLab self-monitoring: Alertmanager](#alertmanager) | Deduplicates, groups, and routes alerts from Prometheus | [✅][alertmanager-omnibus] | [✅][alertmanager-charts] | [⚙][alertmanager-charts] | [✅](https://about.gitlab.com/handbook/engineering/monitoring/) | ❌ | ❌ | CE & EE |
+| [GitLab self-monitoring: Alertmanager](#alertmanager) | Deduplicates, groups, and routes alerts from Prometheus | [⚙][alertmanager-omnibus] | [✅][alertmanager-charts] | [⚙][alertmanager-charts] | [✅](https://about.gitlab.com/handbook/engineering/monitoring/) | ❌ | ❌ | CE & EE |
| [GitLab self-monitoring: Grafana](#grafana) | Metrics dashboard | [⚙][grafana-omnibus] | [⤓][grafana-charts] | [⤓][grafana-charts] | [✅](https://dashboards.gitlab.com/d/RZmbBr7mk/gitlab-triage?refresh=30s) | ❌ | ❌ | CE & EE |
| [GitLab self-monitoring: Sentry](#sentry) | Track errors generated by the GitLab instance | [⤓][sentry-omnibus] | [❌][sentry-charts] | [❌][sentry-charts] | [✅](https://about.gitlab.com/handbook/support/workflows/services/gitlab_com/500_errors.html#searching-sentry) | [⤓][gitlab-yml] | [⤓][gitlab-yml] | CE & EE |
| [GitLab self-monitoring: Jaeger](#jaeger) | View traces generated by the GitLab instance | [❌][jaeger-omnibus] | [❌][jaeger-charts] | [❌][jaeger-charts] | [❌](https://gitlab.com/gitlab-org/omnibus-gitlab/issues/4104) | [⤓][jaeger-source] | [⚙][jaeger-gdk] | CE & EE |
diff --git a/doc/development/git_object_deduplication.md b/doc/development/git_object_deduplication.md
index 81c5f69c7b8..b512d7611d3 100644
--- a/doc/development/git_object_deduplication.md
+++ b/doc/development/git_object_deduplication.md
@@ -10,10 +10,10 @@ GitLab implements Git object deduplication.
## Enabling Git object deduplication via feature flags
-As of GitLab 11.9, Git object deduplication in GitLab is in beta. In this
-document, you can read about the caveats of enabling the feature. Also,
-note that Git object deduplication is limited to forks of public
-projects on hashed repository storage.
+As of GitLab 12.0, Git object deduplication in GitLab is still behind a
+feature flag. In this document, you can read about the effects of
+enabling the feature. Also, note that Git object deduplication is
+limited to forks of public projects on hashed repository storage.
You can enable deduplication globally by setting the `object_pools`
feature flag to `true`:
@@ -51,6 +51,15 @@ configuration. Objects in A that are not in B will remain in A. For this
to work, it is of course critical that **no objects ever get deleted from
B** because A might need them.
+DANGER: **Danger:**
+Do not run `git prune` or `git gc` in pool repositories! This can
+cause data loss in "real" repositories that depend on the pool in
+question.
+
+The danger lies in `git prune`, and `git gc` calls `git prune`. The
+problem is that `git prune`, when running in a pool repository, cannot
+reliable decide if an object is no longer needed.
+
### Git alternates in GitLab: pool repositories
GitLab organizes this object borrowing by creating special **pool
@@ -80,43 +89,10 @@ across a collection of GitLab project repositories at the Git level:
The effectiveness of Git object deduplication in GitLab depends on the
amount of overlap between the pool repository and each of its
-participants. As of GitLab 11.9, we have a somewhat optimistic system.
-The only data that will be deduplicated is the data in the source
-project repository at the time the pool repository is created. That is,
-the data in the source project at the time of the first fork *after* the
-deduplication feature has been enabled.
-
-When we enable the object deduplication feature for
-gitlab.com/gitlab-org/gitlab-ce, which is about 1GB at the time of
-writing, all new forks of that project would be 1GB smaller than they
-would have been without Git object deduplication. So even in its current
-optimistic form, we expect Git object deduplication in GitLab to make a
-difference.
-
-However, if a lot of Git objects get added to the project repositories
-in a pool after the pool repository was created these new Git objects
-will currently (GitLab 11.9) not get deduplicated. Over time, the
-deduplication factor of the pool will get worse and worse.
-
-As an extreme example, if we create an empty repository A, and fork that
-to repository B, behind the scenes we get an object pool P with no
-objects in it at all. If we then push 1GB of Git data to A, and push the
-same Git data to B, it will not get deduplicated, because that data was
-not in A at the time P was created.
-
-This also matters in less extreme examples. Consider a pool P with
-source project A and 500 active forks B1, B2,...,B500. Suppose,
-optimistically, that the forks are fully deduplicated at the start of
-our scenario. Now some time passes and 200MB of new Git data gets added
-to project A. Because of the forking workflow, this data makes also its way
-into the forks B1, ..., B500. That means we would now have 100GB of Git
-data sitting around (500 \* 200MB) across the forks, that could have
-been deduplicated. But because of the way we do deduplication this new
-data will not be deduplicated.
-
-> TODO Add periodic maintenance of object pools to prevent gradual loss
-> of deduplication over time.
-> https://gitlab.com/groups/gitlab-org/-/epics/524
+participants. Each time garbage collection runs on the source project,
+Git objects from the source project will get migrated to the pool
+repository. One by one, as garbage collection runs, other member
+projects will benefit from the new objects that got added to the pool.
## SQL model
@@ -136,6 +112,9 @@ are as follows:
- a `PoolRepository` has exactly one "source `Project`"
(`pool.source_project`)
+> TODO Fix invalid SQL data for pools created prior to GitLab 11.11
+> https://gitlab.com/gitlab-org/gitaly/issues/1653.
+
### Assumptions
- All repositories in a pool must use [hashed
@@ -146,10 +125,6 @@ are as follows:
The Git alternates mechanism relies on direct disk access across
multiple repositories, and we can only assume direct disk access to
be possible within a Gitaly storage shard.
-- All project repositories in a pool must have "Public" visibility in
- GitLab at the time they join. There are gotchas around visibility of
- Git objects across alternates links. This restriction is a defense
- against accidentally leaking private Git data.
- The only two ways to remove a member project from a pool are (1) to
delete the project or (2) to move the project to another Gitaly
storage shard.
@@ -187,17 +162,14 @@ are as follows:
### Consequences
- If a normal Project participating in a pool gets moved to another
- Gitaly storage shard, its "belongs to PoolRepository" relation must
+ Gitaly storage shard, its "belongs to PoolRepository" relation will
be broken. Because of the way moving repositories between shard is
implemented, we will automatically get a fresh self-contained copy
of the project's repository on the new storage shard.
- If the source project of a pool gets moved to another Gitaly storage
- shard or is deleted, we may have to break the "PoolRepository has
- one source Project" relation?
-
-> TODO What happens, or should happen, if a source project changes
-> visibility, is deleted, or moves to another storage shard?
-> https://gitlab.com/gitlab-org/gitaly/issues/1488
+ shard or is deleted the "source project" relation is not broken.
+ However, as of GitLab 12.0 a pool will not fetch from a source
+ unless the source is on the same Gitaly shard.
## Consistency between the SQL pool relation and Gitaly
@@ -209,16 +181,8 @@ repository and a pool.
### Pool existence
If GitLab thinks a pool repository exists (i.e. it exists according to
-SQL), but it does not on the Gitaly server, then certain RPC calls that
-take the object pool as an argument will fail.
-
-> TODO What happens if SQL says the pool repo exists but Gitaly says it
-> does not? https://gitlab.com/gitlab-org/gitaly/issues/1533
-
-If GitLab thinks a pool does not exist, while it does exist on disk,
-that has no direct consequences on its own. However, if other
-repositories on disk borrow objects from this unknown pool repository
-then we risk data loss, see below.
+SQL), but it does not on the Gitaly server, then it will be created on
+the fly by Gitaly.
### Pool relation existence
@@ -226,26 +190,19 @@ There are three different things that can go wrong here.
#### 1. SQL says repo A belongs to pool P but Gitaly says A has no alternate objects
-In this case, we miss out on disk space savings but all RPC's on A itself
-will function fine. As long as Git can find all its objects, it does not
-matter exactly where those objects are.
+In this case, we miss out on disk space savings but all RPC's on A
+itself will function fine. The next time garbage collection runs on A,
+the alternates connection gets established in Gitaly. This is done by
+`Projects::GitDeduplicationService` in gitlab-rails.
#### 2. SQL says repo A belongs to pool P1 but Gitaly says A has alternate objects in pool P2
-If we are not careful, this situation can lead to data loss. During some
-operations (repository maintenance), GitLab will try to re-link A to its
-pool P1. If this clobbers the existing link to P2, then A will loose Git
-objects and become invalid.
-
-Also, keep in mind that if GitLab's database got messed up, it may not
-even know that P2 exists.
-
-> TODO Ensure that Gitaly will not clobber existing, unexpected
-> alternates links. https://gitlab.com/gitlab-org/gitaly/issues/1534
+In this case `Projects::GitDeduplicationService` will throw an exception.
#### 3. SQL says repo A does not belong to any pool but Gitaly says A belongs to P
-This has the same data loss possibility as scenario 2 above.
+In this case `Projects::GitDeduplicationService` will try to
+"re-duplicate" the repository A using the DisconnectGitAlternates RPC.
## Git object deduplication and GitLab Geo
diff --git a/doc/development/gitaly.md b/doc/development/gitaly.md
index 4ef20d5fd74..c8beb808a54 100644
--- a/doc/development/gitaly.md
+++ b/doc/development/gitaly.md
@@ -245,7 +245,7 @@ Here are the steps to gate a new feature in Gitaly behind a feature flag.
// go implementation
} else {
findAllTagsRequests.WithLabelValues("ruby").Inc()
- // ruby impelmentation
+ // ruby implementation
}
```
diff --git a/doc/development/img/architecture_simplified.png b/doc/development/img/architecture_simplified.png
new file mode 100644
index 00000000000..1698c167c5e
--- /dev/null
+++ b/doc/development/img/architecture_simplified.png
Binary files differ
diff --git a/doc/development/new_fe_guide/development/accessibility.md b/doc/development/new_fe_guide/development/accessibility.md
index 8420a504ec4..81a29170129 100644
--- a/doc/development/new_fe_guide/development/accessibility.md
+++ b/doc/development/new_fe_guide/development/accessibility.md
@@ -21,6 +21,7 @@ On the other hand, if an icon is crucial to understand the context we should do
## Form inputs
In forms we should use the `for` attribute in the label statement:
+
```
<div>
<label for="name">Fill in your name:</label>
diff --git a/doc/development/testing_guide/best_practices.md b/doc/development/testing_guide/best_practices.md
index 82439c94c5a..71e3b7740cb 100644
--- a/doc/development/testing_guide/best_practices.md
+++ b/doc/development/testing_guide/best_practices.md
@@ -17,7 +17,7 @@ our test design. We can find some helpful heuristics documented in the Handbook
## Run tests against MySQL
-By default, tests are only run againts PostgreSQL, but you can run them on
+By default, tests are only run against PostgreSQL, but you can run them on
demand against MySQL by following one of the following conventions:
| Convention | Valid example |
diff --git a/doc/development/testing_guide/end_to_end/quick_start_guide.md b/doc/development/testing_guide/end_to_end/quick_start_guide.md
index afe76acf9c9..9f43f4ebd1c 100644
--- a/doc/development/testing_guide/end_to_end/quick_start_guide.md
+++ b/doc/development/testing_guide/end_to_end/quick_start_guide.md
@@ -557,7 +557,7 @@ The code should look like this: `filter_output = search_field_tag search_id, nil
> Classes starting with `qa-` are used for testing purposes only, and by defining such classes in the elements we add **testability** in the application.
-> When defining a class like `qa-labels-block`, it is transformed into `:labels_block` for usage in the Page Objects. So, `qa-edit-link-labels` is tranformed into `:edit_link_labels`, `qa-dropdown-menu-labels` is transformed into `:dropdown_menu_labels`, and `qa-dropdown-input-field` is transformed into `:dropdown_input_field`. Also, we use a [sanity test](https://gitlab.com/gitlab-org/gitlab-ce/tree/master/qa/qa/page#how-did-we-solve-fragile-tests-problem) to check that defined elements have their respective `qa-` selectors in the specified views.
+> When defining a class like `qa-labels-block`, it is transformed into `:labels_block` for usage in the Page Objects. So, `qa-edit-link-labels` is transformed into `:edit_link_labels`, `qa-dropdown-menu-labels` is transformed into `:dropdown_menu_labels`, and `qa-dropdown-input-field` is transformed into `:dropdown_input_field`. Also, we use a [sanity test](https://gitlab.com/gitlab-org/gitlab-ce/tree/master/qa/qa/page#how-did-we-solve-fragile-tests-problem) to check that defined elements have their respective `qa-` selectors in the specified views.
> We did not define the `qa-labels-block` class in the `app/views/shared/issuable/_sidebar.html.haml` file because it was already there to be used.
diff --git a/doc/gitlab-basics/README.md b/doc/gitlab-basics/README.md
index 00ac6d6b650..0c268eff9f1 100644
--- a/doc/gitlab-basics/README.md
+++ b/doc/gitlab-basics/README.md
@@ -24,6 +24,7 @@ The following are guides to basic GitLab functionality:
- [Add an image](add-image.md), to add new images to a project's repository.
- [Create an issue](../user/project/issues/create_new_issue.md), to start collaborating within a project.
- [Create a merge request](add-merge-request.md), to request changes made in a branch be merged into a project's repository.
+- See how these features come together in the [GitLab Flow introduction video](https://youtu.be/InKNIvky2KE) and [GitLab Flow page](../workflow/gitlab_flow.md).
## Git basics
diff --git a/doc/install/installation.md b/doc/install/installation.md
index 10436a15a9e..eb484dde545 100644
--- a/doc/install/installation.md
+++ b/doc/install/installation.md
@@ -250,11 +250,11 @@ page](https://golang.org/dl).
# Remove former Go installation folder
sudo rm -rf /usr/local/go
-curl --remote-name --progress https://dl.google.com/go/go1.10.3.linux-amd64.tar.gz
-echo 'fa1b0e45d3b647c252f51f5e1204aba049cde4af177ef9f2181f43004f901035 go1.10.3.linux-amd64.tar.gz' | shasum -a256 -c - && \
- sudo tar -C /usr/local -xzf go1.10.3.linux-amd64.tar.gz
+curl --remote-name --progress https://dl.google.com/go/go1.11.10.linux-amd64.tar.gz
+echo 'aefaa228b68641e266d1f23f1d95dba33f17552ba132878b65bb798ffa37e6d0 go1.11.10.linux-amd64.tar.gz' | shasum -a256 -c - && \
+ sudo tar -C /usr/local -xzf go1.11.10.linux-amd64.tar.gz
sudo ln -sf /usr/local/go/bin/{go,godoc,gofmt} /usr/local/bin/
-rm go1.10.3.linux-amd64.tar.gz
+rm go1.11.10.linux-amd64.tar.gz
```
## 4. Node
diff --git a/doc/install/requirements.md b/doc/install/requirements.md
index 107d48fb90c..ee3d17704a2 100644
--- a/doc/install/requirements.md
+++ b/doc/install/requirements.md
@@ -168,14 +168,14 @@ CREATE EXTENSION postgres_fdw;
## Unicorn Workers
-It's possible to increase the amount of unicorn workers and this will usually help to reduce the response time of the applications and increase the ability to handle parallel requests.
-
For most instances we recommend using: CPU cores + 1 = unicorn workers.
So for a machine with 2 cores, 3 unicorn workers is ideal.
For all machines that have 2GB and up we recommend a minimum of three unicorn workers.
If you have a 1GB machine we recommend to configure only two Unicorn workers to prevent excessive swapping.
+As long as you have enough available CPU and memory capacity, it's okay to increase the number of unicorn workers and this will usually help to reduce the response time of the applications and increase the ability to handle parallel requests.
+
To change the Unicorn workers when you have the Omnibus package (which defaults to the recommendation above) please see [the Unicorn settings in the Omnibus GitLab documentation](https://docs.gitlab.com/omnibus/settings/unicorn.html).
## Redis and Sidekiq
diff --git a/doc/integration/elasticsearch.md b/doc/integration/elasticsearch.md
index 57a5a42fbed..6064c417900 100644
--- a/doc/integration/elasticsearch.md
+++ b/doc/integration/elasticsearch.md
@@ -351,8 +351,6 @@ There are several rake tasks available to you via the command line:
- This removes the GitLab index on the Elasticsearch instance.
- [sudo gitlab-rake gitlab:elastic:recreate_index](https://gitlab.com/gitlab-org/gitlab-ee/blob/master/ee/lib/tasks/gitlab/elastic.rake)
- Does the same thing as `sudo gitlab-rake gitlab:elastic:create_empty_index`
-- [sudo gitlab-rake gitlab:elastic:add_feature_visibility_levels_to_project](https://gitlab.com/gitlab-org/gitlab-ee/blob/master/ee/lib/tasks/gitlab/elastic.rake)
- - Adds visibility information to the indices for projects.
- [sudo gitlab-rake gitlab:elastic:index_snippets](https://gitlab.com/gitlab-org/gitlab-ee/blob/master/ee/lib/tasks/gitlab/elastic.rake)
- Performs an Elasticsearch import that indexes the snippets data.
diff --git a/doc/integration/jenkins.md b/doc/integration/jenkins.md
index f60333aa07c..5950737b964 100644
--- a/doc/integration/jenkins.md
+++ b/doc/integration/jenkins.md
@@ -19,6 +19,9 @@ GitLab's Jenkins integration allows you to trigger a Jenkins build when you
push code to a repository, or when a merge request is created. Additionally,
it shows the pipeline status on merge requests widgets and on the project's home page.
+Videos are also available on [GitLab workflow with Jira issues and Jenkins pipelines](https://youtu.be/Jn-_fyra7xQ)
+and [Migrating from Jenkins to GitLab](https://www.youtube.com/watch?v=RlEVGOpYF5Y).
+
## Use cases
- Suppose you are new to GitLab, and want to keep using Jenkins until you prepare
@@ -30,6 +33,8 @@ running with Jenkins, but view the results in your project's repository in GitLa
therefore, you opt for keep using Jenkins to build your apps. Show the results of your
pipelines directly in GitLab.
+For a real use case, read the blog post [Continuous integration: From Jenkins to GitLab using Docker](https://about.gitlab.com/2017/07/27/docker-my-precious/).
+
## Requirements
* [Jenkins GitLab Plugin](https://wiki.jenkins.io/display/JENKINS/GitLab+Plugin)
diff --git a/doc/migrate_ci_to_ce/README.md b/doc/migrate_ci_to_ce/README.md
index 4c4b423f40f..7659b743311 100644
--- a/doc/migrate_ci_to_ce/README.md
+++ b/doc/migrate_ci_to_ce/README.md
@@ -1,3 +1,7 @@
+---
+type: howto
+---
+
# Migrate GitLab CI to GitLab CE or EE
Beginning with version 8.0 of GitLab Community Edition (CE) and Enterprise
@@ -333,7 +337,9 @@ restoration](../raketasks/backup_restore.md) guide.
## Troubleshooting
### show:secrets problem (Omnibus-only)
+
If you see errors like this:
+
```
Missing `secret_key_base` or `db_key_base` for 'production' environment. The secrets will be generated and stored in `config/secrets.yml`
rake aborted!
@@ -344,6 +350,7 @@ This can happen if you are updating from versions prior to 7.13 straight to 8.0.
The fix for this is to update to Omnibus 7.14 first and then update it to 8.0.
### Permission denied when accessing /var/opt/gitlab/gitlab-ci/builds
+
To fix that issue you have to change builds/ folder permission before doing final backup:
```
sudo chown -R gitlab-ci:gitlab-ci /var/opt/gitlab/gitlab-ci/builds
@@ -355,8 +362,10 @@ sudo chown git:git /var/opt/gitlab/gitlab-ci/builds
```
### Problems when importing CI database to GitLab
+
If you were migrating CI database from MySQL to PostgreSQL manually you can see errors during import about missing sequences:
-```
+
+```sql
ALTER SEQUENCE
ERROR: relation "ci_builds_id_seq" does not exist
ERROR: relation "ci_commits_id_seq" does not exist
@@ -373,9 +382,9 @@ CREATE TABLE
To fix that you need to apply this SQL statement before doing final backup:
-```sql
-## Omnibus GitLab
+Omnibus GitLab installations:
+```sql
gitlab-ci-rails dbconsole <<EOF
-- ALTER TABLES - DROP DEFAULTS
ALTER TABLE ONLY ci_application_settings ALTER COLUMN id DROP DEFAULT;
@@ -428,9 +437,11 @@ ALTER TABLE ONLY ci_triggers ALTER COLUMN id SET DEFAULT nextval('ci_triggers_id
ALTER TABLE ONLY ci_variables ALTER COLUMN id SET DEFAULT nextval('ci_variables_id_seq'::regclass);
ALTER TABLE ONLY ci_web_hooks ALTER COLUMN id SET DEFAULT nextval('ci_web_hooks_id_seq'::regclass);
EOF
+```
-## Source installations
+Source installations:
+```
cd /home/gitlab_ci/gitlab-ci
sudo -u gitlab_ci -H bundle exec rails dbconsole production <<EOF
... COPY SQL STATEMENTS FROM ABOVE ...
diff --git a/doc/policy/maintenance.md b/doc/policy/maintenance.md
index 1d656574acd..72bace3d282 100644
--- a/doc/policy/maintenance.md
+++ b/doc/policy/maintenance.md
@@ -1,8 +1,15 @@
-# GitLab Maintenance Policy
+---
+type: concepts
+---
+
+# GitLab Release and Maintenance Policy
+
+GitLab has strict policies governing version naming, as well as release pace for major, minor,
+patch and security releases. New releases are usually announced on the [GitLab blog](https://about.gitlab.com/blog/categories/releases/).
## Versioning
-GitLab follows the [Semantic Versioning](http://semver.org/) for its releases:
+GitLab uses [Semantic Versioning](http://semver.org/) for its releases:
`(Major).(Minor).(Patch)` in a [pragmatic way](https://gist.github.com/jashkenas/cbd2b088e20279ae2c8e).
For example, for GitLab version 10.5.7:
@@ -15,9 +22,9 @@ Any part of the version number can increment into multiple digits, for example,
The following table describes the version types and their release cadence:
-| Version type | Description | Cadence |
-|:-------------|:----------|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------|
-| Major | For significant changes, or when any backward-incompatible changes are introduced to the public API. | Yearly. The next major release is GitLab 12.0 on June 22, 2019. Subsequent major releases will be scheduled for May 22 each year, by default. | |
+| Version type | Description | Cadence |
+|:-------------|:------------|:--------|
+| Major | For significant changes, or when any backward-incompatible changes are introduced to the public API. | Yearly. The next major release is GitLab 12.0 on June 22, 2019. Subsequent major releases will be scheduled for May 22 each year, by default. |
| Minor | For when new backward-compatible functionality is introduced to the public API, a minor feature is introduced, or when a set of smaller features is rolled out. | Monthly on the 22nd. |
| Patch | For backward-compatible bug fixes that fix incorrect behavior. See [Patch releases](#patch-releases). | As needed. |
@@ -75,10 +82,10 @@ that could change behavior in the next major release.
Please see the table below for some examples:
| Latest stable version | Your version | Recommended upgrade path | Note |
-| -------------- | ------------ | ------------------------ | ---------------- |
-| 9.4.5 | 8.13.4 | `8.13.4` -> `8.17.7` -> `9.4.5` | `8.17.7` is the last version in version `8` |
-| 10.1.4 | 8.13.4 | `8.13.4 -> 8.17.7 -> 9.5.10 -> 10.1.4` | `8.17.7` is the last version in version `8`, `9.5.10` is the last version in version `9` |
-| 11.3.4 | 8.13.4 | `8.13.4` -> `8.17.7` -> `9.5.10` -> `10.8.7` -> `11.3.4` | `8.17.7` is the last version in version `8`, `9.5.10` is the last version in version `9`, `10.8.7` is the last version in version `10` |
+| --------------------- | ------------ | ------------------------ | ---- |
+| 9.4.5 | 8.13.4 | `8.13.4` -> `8.17.7` -> `9.4.5` | `8.17.7` is the last version in version `8` |
+| 10.1.4 | 8.13.4 | `8.13.4 -> 8.17.7 -> 9.5.10 -> 10.1.4` | `8.17.7` is the last version in version `8`, `9.5.10` is the last version in version `9` |
+| 11.3.4 | 8.13.4 | `8.13.4` -> `8.17.7` -> `9.5.10` -> `10.8.7` -> `11.3.4` | `8.17.7` is the last version in version `8`, `9.5.10` is the last version in version `9`, `10.8.7` is the last version in version `10` |
More information about the release procedures can be found in our
[release documentation](https://gitlab.com/gitlab-org/release/docs). You may also want to read our
diff --git a/doc/public_access/public_access.md b/doc/public_access/public_access.md
index 8601551e3bd..b1637181855 100644
--- a/doc/public_access/public_access.md
+++ b/doc/public_access/public_access.md
@@ -1,13 +1,12 @@
-# Public access
-
-GitLab allows [Owners](../user/permissions.md) to change a projects' visibility in order to be accessed
-**publicly** or **internally**.
+---
+type: reference
+---
-Projects with either of these visibility levels will be listed in the
-public access directory (`/public` under your GitLab instance).
-Here is the [GitLab.com example](https://gitlab.com/public).
+# Public access
-Internal projects will only be available to authenticated users.
+GitLab allows [Owners](../user/permissions.md) to set a projects' visibility as **public**, **internal**
+or **private**. These visibility levels affect who can see the project in the
+public access directory (`/public` under your GitLab instance), like at [https://gitlab.com/public]().
## Visibility of projects
@@ -15,26 +14,26 @@ Internal projects will only be available to authenticated users.
Public projects can be cloned **without any** authentication.
-They will also be listed on the public access directory (`/public`).
+They will be listed in the public access directory (`/public`) for all users.
-**Any logged in user** will have [Guest](../user/permissions.md)
-permissions on the repository.
+**Any logged in user** will have [Guest permissions](../user/permissions.md)
+on the repository.
### Internal projects
Internal projects can be cloned by any logged in user.
-They will also be listed on the public access directory (`/public`) for logged
+They will also be listed in the public access directory (`/public`), but only for logged
in users.
-Any logged in user will have [Guest](../user/permissions.md) permissions
+Any logged in user will have [Guest permissions](../user/permissions.md)
on the repository.
### Private projects
-Private projects can only be cloned and viewed by project members, and
-they will only appear to project members on the public access directory
-(`https://gitlab.example.com/public`).
+Private projects can only be cloned and viewed by project members.
+
+They will appear in the public access directory (`/public`) for project members only.
### How to change project visibility
@@ -43,10 +42,10 @@ they will only appear to project members on the public access directory
## Visibility of groups
->**Note:**
-[Starting with][3323] GitLab 8.6, the group visibility has changed and can be
-configured the same way as projects. In previous versions, a group's page was
-always visible to all users.
+NOTE: **Note:**
+[Starting with](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/3323) GitLab 8.6,
+the group visibility has changed and can be configured the same way as projects.
+In previous versions, a group's page was always visible to all users.
Like with projects, the visibility of a group can be set to dictate whether
anonymous users, all signed in users, or only explicit group members can view
@@ -54,8 +53,6 @@ it. The restriction for visibility levels on the application setting level also
applies to groups, so if that's set to internal, the explore page will be empty
for anonymous users. The group page now has a visibility level icon.
-[3323]: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/3323
-
## Visibility of users
The public page of a user, located at `/username`, is always visible whether
@@ -76,3 +73,15 @@ snippet:
This is useful to prevent people exposing their repositories to public
by accident. The restricted visibility settings do not apply to admin users.
+
+<!-- ## Troubleshooting
+
+Include any troubleshooting steps that you can foresee. If you know beforehand what issues
+one might have when setting this up, or when something is changed, or on upgrading, it's
+important to describe those, too. Think of things that may go wrong and include them here.
+This is important to minimize requests for support, and to avoid doc comments with
+questions that you know someone might ask.
+
+Each scenario can be a third-level heading, e.g. `### Getting error message X`.
+If you have none to add when creating a doc, leave this section in place
+but commented out to help encourage others to add to it in the future. -->
diff --git a/doc/push_rules/push_rules.md b/doc/push_rules/push_rules.md
index e44eab2556e..b2d626a0a74 100644
--- a/doc/push_rules/push_rules.md
+++ b/doc/push_rules/push_rules.md
@@ -1,6 +1,11 @@
+---
+type: reference, howto
+---
+
# Push Rules **[STARTER]**
-Gain additional control over pushes to your repository.
+Gain additional control over what can and can't be pushed to your repository by using
+regular expressions to reject pushes based on commit contents, branch names or file details.
## Overview
@@ -33,7 +38,7 @@ will be accepted.
### Restrict branch names
-Let's assume there's a strictly policy for branch names in your company, and
+Let's assume there's a strict policy for branch names in your company, and
you want the branches to start with a certain name because you have different
GitLab CI jobs (`feature`, `hotfix`, `docker`, `android`, etc.) that rely on the
branch name.
@@ -46,7 +51,7 @@ will get rejected.
## Enabling push rules
->**Note:**
+NOTE: **Note:**
GitLab administrators can set push rules globally under
**Admin area > Push Rules** that all new projects will inherit. You can later
override them in a project's settings.
@@ -71,8 +76,8 @@ The following options are available.
| Prohibited file names | **Starter** 7.10 | Any committed filenames that match this regular expression are not allowed to be pushed. Leave empty to allow any filenames. |
| Maximum file size | **Starter** 7.12 | Pushes that contain added or updated files that exceed this file size (in MB) are rejected. Set to 0 to allow files of any size. |
->**Tip:**
-GitLab uses [RE2 syntax](https://github.com/google/re2/wiki/Syntax) for regular expressions in push rules. You can check your regular expressions at <https://regex-golang.appspot.com>.
+TIP: **Tip:**
+GitLab uses [RE2 syntax](https://github.com/google/re2/wiki/Syntax) for regular expressions in push rules, and you can test them at the [GoLang regex tester](https://regex-golang.appspot.com).
## Prevent pushing secrets to the repository
@@ -86,7 +91,7 @@ pushes to the repository when a file matches a regular expression as read from
[`files_blacklist.yml`][list] (make sure you are at the right branch
as your GitLab version when viewing this file).
-NOTE: **Note**:
+NOTE: **Note:**
Files already committed won't get restricted by this push rule.
Below is an example list of what will be rejected by these regular expressions:
@@ -148,6 +153,18 @@ pry.history
bash_history
```
+<!-- ## Troubleshooting
+
+Include any troubleshooting steps that you can foresee. If you know beforehand what issues
+one might have when setting this up, or when something is changed, or on upgrading, it's
+important to describe those, too. Think of things that may go wrong and include them here.
+This is important to minimize requests for support, and to avoid doc comments with
+questions that you know someone might ask.
+
+Each scenario can be a third-level heading, e.g. `### Getting error message X`.
+If you have none to add when creating a doc, leave this section in place
+but commented out to help encourage others to add to it in the future. -->
+
[protected-branches]: ../user/project/protected_branches.md
[signing-commits]: ../user/project/repository/gpg_signed_commits/index.md
[ee-385]: https://gitlab.com/gitlab-org/gitlab-ee/issues/385
diff --git a/doc/security/README.md b/doc/security/README.md
index a90127e0356..c48d5bc2065 100644
--- a/doc/security/README.md
+++ b/doc/security/README.md
@@ -1,5 +1,6 @@
---
comments: false
+type: index
---
# Security
diff --git a/doc/security/crime_vulnerability.md b/doc/security/crime_vulnerability.md
index d61a205d954..9665cc0337f 100644
--- a/doc/security/crime_vulnerability.md
+++ b/doc/security/crime_vulnerability.md
@@ -1,3 +1,7 @@
+---
+type: reference
+---
+
# How we manage the TLS protocol CRIME vulnerability
> CRIME ("Compression Ratio Info-leak Made Easy") is a security exploit against
@@ -7,15 +11,15 @@ authentication cookies, it allows an attacker to perform session hijacking on an
authenticated web session, allowing the launching of further attacks.
([CRIME](https://en.wikipedia.org/w/index.php?title=CRIME&oldid=692423806))
-### Description
+## Description
-The TLS Protocol CRIME Vulnerability affects compression over HTTPS, therefore
-it warns against using SSL Compression (for example gzip) or SPDY which
-optionally uses compression as well.
+The TLS Protocol CRIME Vulnerability affects systems that use data compression
+over HTTPS. Your system might be vulnerable to the CRIME vulnerability if you use
+SSL Compression (for example, gzip) or SPDY (which optionally uses compression).
GitLab supports both gzip and [SPDY][ngx-spdy] and mitigates the CRIME
-vulnerability by deactivating gzip when HTTPS is enabled. You can see the
-sources of the files in question:
+vulnerability by deactivating gzip when HTTPS is enabled. The sources of the
+files are here:
- [Source installation NGINX file][source-nginx]
- [Omnibus installation NGINX file][omnibus-nginx]
@@ -24,7 +28,7 @@ Although SPDY is enabled in Omnibus installations, CRIME relies on compression
(the 'C') and the default compression level in NGINX's SPDY module is 0
(no compression).
-### Nessus
+## Nessus
The Nessus scanner, [reports a possible CRIME vulnerability][nessus] in GitLab
similar to the following format:
@@ -45,12 +49,12 @@ SPDY support earlier than version 4 is advertised.
```
From the report above it is important to note that Nessus is only checking if
-TLS advertises the SPDY protocol earlier than version 4, it does not perform an
-attack nor does it check if compression is enabled. With just this approach, it
+TLS advertises the SPDY protocol earlier than version 4. It does not perform an
+attack nor does it check if compression is enabled. The Nessus scanner alone
cannot tell that SPDY's compression is disabled and not subject to the CRIME
vulnerability.
-### References
+## References
- Nginx ["Module ngx_http_spdy_module"][ngx-spdy]
- Tenable Network Security, Inc. ["Transport Layer Security (TLS) Protocol CRIME Vulnerability"][nessus]
@@ -61,3 +65,15 @@ vulnerability.
[ngx-spdy]: http://nginx.org/en/docs/http/ngx_http_spdy_module.html
[nessus]: https://www.tenable.com/plugins/index.php?view=single&id=62565
[wiki-crime]: https://en.wikipedia.org/wiki/CRIME
+
+<!-- ## Troubleshooting
+
+Include any troubleshooting steps that you can foresee. If you know beforehand what issues
+one might have when setting this up, or when something is changed, or on upgrading, it's
+important to describe those, too. Think of things that may go wrong and include them here.
+This is important to minimize requests for support, and to avoid doc comments with
+questions that you know someone might ask.
+
+Each scenario can be a third-level heading, e.g. `### Getting error message X`.
+If you have none to add when creating a doc, leave this section in place
+but commented out to help encourage others to add to it in the future. -->
diff --git a/doc/security/information_exclusivity.md b/doc/security/information_exclusivity.md
index 22756232025..62a20d3f257 100644
--- a/doc/security/information_exclusivity.md
+++ b/doc/security/information_exclusivity.md
@@ -1,9 +1,36 @@
+---
+type: concepts
+---
# Information exclusivity
-Git is a distributed version control system (DVCS).
-This means that everyone that works with the source code has a local copy of the complete repository.
-In GitLab every project member that is not a guest (so reporters, developers and maintainers) can clone the repository to get a local copy.
-After obtaining this local copy the user can upload the full repository anywhere, including another project under their control or another server.
-The consequence is that you can't build access controls that prevent the intentional sharing of source code by users that have access to the source code.
-This is an inherent feature of a DVCS and all git management systems have this limitation.
-Obviously you can take steps to prevent unintentional sharing and information destruction, this is why only some people are allowed to invite others and nobody can force push a protected branch.
+Git is a distributed version control system (DVCS). This means that everyone
+who works with the source code has a local copy of the complete repository.
+
+In GitLab every project member that is not a guest (reporters, developers, and
+maintainers) can clone the repository to create a local copy. After obtaining
+a local copy, the user can upload the full repository anywhere, including to
+another project that is under their control, or onto another server.
+
+Therefore, it is impossible to build access controls that prevent the
+intentional sharing of source code by users that have access to the source code.
+
+This is an inherent feature of a DVCS. All git management systems have this
+limitation.
+
+You can take steps to prevent unintentional sharing and information
+destruction. This limitation is the reason why only certain people are allowed
+to [add users to a project](../user/project/members/index.md)
+and why only a GitLab admin can [force push a protected
+branch](../user/project/protected_branches.md).
+
+<!-- ## Troubleshooting
+
+Include any troubleshooting steps that you can foresee. If you know beforehand what issues
+one might have when setting this up, or when something is changed, or on upgrading, it's
+important to describe those, too. Think of things that may go wrong and include them here.
+This is important to minimize requests for support, and to avoid doc comments with
+questions that you know someone might ask.
+
+Each scenario can be a third-level heading, e.g. `### Getting error message X`.
+If you have none to add when creating a doc, leave this section in place
+but commented out to help encourage others to add to it in the future. -->
diff --git a/doc/security/password_length_limits.md b/doc/security/password_length_limits.md
index d21b26a43e8..d78293c75c6 100644
--- a/doc/security/password_length_limits.md
+++ b/doc/security/password_length_limits.md
@@ -1,11 +1,28 @@
+---
+type: reference, howto
+---
# Custom password length limits
-If you want to enforce longer user passwords you can create an extra Devise initializer with the steps below.
+If you want to enforce longer user passwords you can create an extra Devise
+initializer with the steps below.
-If you do not use the `devise_password_length.rb` initializer the password length is set to a minimum of 8 characters in `config/initializers/devise.rb`.
+If you do not use the `devise_password_length.rb` initializer the password
+length is set to a minimum of 8 characters in `config/initializers/devise.rb`.
```bash
cd /home/git/gitlab
sudo -u git -H cp config/initializers/devise_password_length.rb.example config/initializers/devise_password_length.rb
sudo -u git -H editor config/initializers/devise_password_length.rb # inspect and edit the new password length limits
```
+
+<!-- ## Troubleshooting
+
+Include any troubleshooting steps that you can foresee. If you know beforehand what issues
+one might have when setting this up, or when something is changed, or on upgrading, it's
+important to describe those, too. Think of things that may go wrong and include them here.
+This is important to minimize requests for support, and to avoid doc comments with
+questions that you know someone might ask.
+
+Each scenario can be a third-level heading, e.g. `### Getting error message X`.
+If you have none to add when creating a doc, leave this section in place
+but commented out to help encourage others to add to it in the future. -->
diff --git a/doc/security/rack_attack.md b/doc/security/rack_attack.md
index 66081d7e376..fa4b0d1fb09 100644
--- a/doc/security/rack_attack.md
+++ b/doc/security/rack_attack.md
@@ -1,24 +1,28 @@
+---
+type: reference, howto
+---
# Rack Attack
-Rack Attack, also known as Rack::Attack, is [a rubygem](https://github.com/kickstarter/rack-attack)
+[Rack Attack](https://github.com/kickstarter/rack-attack), also known as Rack::Attack, is a Ruby gem
that is meant to protect GitLab with the ability to customize throttling and
-blocking user IPs.
+to block user IP addresses.
+
You can prevent brute-force passwords attacks, scrapers, or any other offenders
-by throttling requests from IP addresses making large volumes of requests.
-In case you find throttling is not enough to protect you against abusive clients,
-Rack Attack offers IP whitelisting, blacklisting, Fail2ban style filtering and
+by throttling requests from IP addresses that are making large volumes of requests.
+If you find throttling is not enough to protect you against abusive clients,
+Rack Attack offers IP whitelisting, blacklisting, Fail2ban style filtering, and
tracking.
**Note:** Starting with 11.2, Rack Attack is disabled by default. To continue
-using this feature, please enable it by [configuring `gitlab.rb` as described in Settings](#settings).
+using Rack Attack, please enable it by [configuring `gitlab.rb` as described in Settings](#settings).
By default, user sign-in, user sign-up (if enabled), and user password reset is
limited to 6 requests per minute. After trying for 6 times, the client will
have to wait for the next minute to be able to try again.
-If you installed or upgraded GitLab by following the [official guides](../install/README.md)
-this should be disabled by default. If your instance is not exposed to any incoming
-connections, it is recommended to leave Rack Attack disabled.
+If you installed or upgraded GitLab by following the [official guides](../install/README.md),
+Rack Attack should be disabled by default. If your instance is not exposed to any incoming
+connections, it is recommended that you leave Rack Attack disabled.
For more information on how to use these options check out
[rack-attack README](https://github.com/kickstarter/rack-attack/blob/master/README.md).
@@ -27,7 +31,7 @@ For more information on how to use these options check out
**Omnibus GitLab**
-1. Open `/etc/gitlab/gitlab.rb` with you editor
+1. Open `/etc/gitlab/gitlab.rb` with your editor
1. Add the following:
```ruby
@@ -53,7 +57,7 @@ The following settings can be configured:
For example, `["127.0.0.1", "127.0.0.2", "127.0.0.3"]`.
- `maxretry`: The maximum amount of times a request can be made in the
specified time.
-- `findtime`: The maximum amount of time failed requests can count against an IP
+- `findtime`: The maximum amount of time that failed requests can count against an IP
before it's blacklisted (in seconds).
- `bantime`: The total amount of time that a blacklisted IP will be blocked (in
seconds).
diff --git a/doc/security/reset_root_password.md b/doc/security/reset_root_password.md
index 6a882ed6fe5..a58d70f0ff2 100644
--- a/doc/security/reset_root_password.md
+++ b/doc/security/reset_root_password.md
@@ -1,8 +1,11 @@
+---
+type: howto
+---
# How to reset your root password
-Log into your server with root privileges. Then start a Ruby on Rails console.
+To reset your root password, first log into your server with root privileges.
-Start the console with this command:
+Start a Ruby on Rails console with this command:
```bash
gitlab-rails console production
@@ -38,3 +41,15 @@ user.save!
```
Exit the console and try to login with your new password.
+
+<!-- ## Troubleshooting
+
+Include any troubleshooting steps that you can foresee. If you know beforehand what issues
+one might have when setting this up, or when something is changed, or on upgrading, it's
+important to describe those, too. Think of things that may go wrong and include them here.
+This is important to minimize requests for support, and to avoid doc comments with
+questions that you know someone might ask.
+
+Each scenario can be a third-level heading, e.g. `### Getting error message X`.
+If you have none to add when creating a doc, leave this section in place
+but commented out to help encourage others to add to it in the future. -->
diff --git a/doc/security/ssh_keys_restrictions.md b/doc/security/ssh_keys_restrictions.md
index 6b6a8a06cc9..ae4cc44519e 100644
--- a/doc/security/ssh_keys_restrictions.md
+++ b/doc/security/ssh_keys_restrictions.md
@@ -1,3 +1,6 @@
+---
+type: reference, howto
+---
# Restrict allowed SSH key technologies and minimum length
`ssh-keygen` allows users to create RSA keys with as few as 768 bits, which
@@ -25,3 +28,15 @@ An icon will be visible to the user of a restricted key in the SSH keys section
![Restricted SSH key icon](img/ssh_keys_restricted_key_icon.png)
Hovering over this icon will tell you why the key is restricted.
+
+<!-- ## Troubleshooting
+
+Include any troubleshooting steps that you can foresee. If you know beforehand what issues
+one might have when setting this up, or when something is changed, or on upgrading, it's
+important to describe those, too. Think of things that may go wrong and include them here.
+This is important to minimize requests for support, and to avoid doc comments with
+questions that you know someone might ask.
+
+Each scenario can be a third-level heading, e.g. `### Getting error message X`.
+If you have none to add when creating a doc, leave this section in place
+but commented out to help encourage others to add to it in the future. -->
diff --git a/doc/security/two_factor_authentication.md b/doc/security/two_factor_authentication.md
index 2ece4ed3fc9..ad5daef805a 100644
--- a/doc/security/two_factor_authentication.md
+++ b/doc/security/two_factor_authentication.md
@@ -1,3 +1,6 @@
+---
+type: howto
+---
# Enforce Two-factor Authentication (2FA)
Two-factor Authentication (2FA) provides an additional level of security to your
@@ -55,3 +58,15 @@ sudo -u git -H bundle exec rake gitlab:two_factor:disable_for_all_users RAILS_EN
CAUTION: **Caution:**
This is a permanent and irreversible action. Users will have to
reactivate 2FA from scratch if they want to use it again.
+
+<!-- ## Troubleshooting
+
+Include any troubleshooting steps that you can foresee. If you know beforehand what issues
+one might have when setting this up, or when something is changed, or on upgrading, it's
+important to describe those, too. Think of things that may go wrong and include them here.
+This is important to minimize requests for support, and to avoid doc comments with
+questions that you know someone might ask.
+
+Each scenario can be a third-level heading, e.g. `### Getting error message X`.
+If you have none to add when creating a doc, leave this section in place
+but commented out to help encourage others to add to it in the future. -->
diff --git a/doc/security/unlock_user.md b/doc/security/unlock_user.md
index d5ecef7f605..75cf754e197 100644
--- a/doc/security/unlock_user.md
+++ b/doc/security/unlock_user.md
@@ -1,8 +1,12 @@
+---
+type: howto
+---
# How to unlock a locked user
-Log into your server with root privileges. Then start a Ruby on Rails console.
+To unlock a locked user, first log into your server with root privileges.
+
+Start a Ruby on Rails console with this command:
-Start the console with this command:
```bash
gitlab-rails console production
@@ -29,3 +33,15 @@ user.unlock_access!
```
Exit the console, the user should now be able to log in again.
+
+<!-- ## Troubleshooting
+
+Include any troubleshooting steps that you can foresee. If you know beforehand what issues
+one might have when setting this up, or when something is changed, or on upgrading, it's
+important to describe those, too. Think of things that may go wrong and include them here.
+This is important to minimize requests for support, and to avoid doc comments with
+questions that you know someone might ask.
+
+Each scenario can be a third-level heading, e.g. `### Getting error message X`.
+If you have none to add when creating a doc, leave this section in place
+but commented out to help encourage others to add to it in the future. -->
diff --git a/doc/security/user_email_confirmation.md b/doc/security/user_email_confirmation.md
index 8c07e11dcb1..f0af0a7ac6a 100644
--- a/doc/security/user_email_confirmation.md
+++ b/doc/security/user_email_confirmation.md
@@ -1,7 +1,23 @@
+---
+type: howto
+---
# User email confirmation at sign-up
-GitLab admin can enable email confirmation on sign-up, if you want to confirm all
-user emails before they are able to sign-in.
+GitLab can be configured to require confirmation of a user's email address when
+the user signs up. When this setting is enabled, the user is unable to sign in until
+they confirm their email address.
In the Admin area under **Settings** (`/admin/application_settings`), go to section
-**Sign-up Restrictions** and look for **Send confirmation email on sign-up** option.
+**Sign-up Restrictions** and look for the **Send confirmation email on sign-up** option.
+
+<!-- ## Troubleshooting
+
+Include any troubleshooting steps that you can foresee. If you know beforehand what issues
+one might have when setting this up, or when something is changed, or on upgrading, it's
+important to describe those, too. Think of things that may go wrong and include them here.
+This is important to minimize requests for support, and to avoid doc comments with
+questions that you know someone might ask.
+
+Each scenario can be a third-level heading, e.g. `### Getting error message X`.
+If you have none to add when creating a doc, leave this section in place
+but commented out to help encourage others to add to it in the future. -->
diff --git a/doc/security/user_file_uploads.md b/doc/security/user_file_uploads.md
index 98493d33b00..00a2607b607 100644
--- a/doc/security/user_file_uploads.md
+++ b/doc/security/user_file_uploads.md
@@ -1,11 +1,30 @@
+---
+type: reference
+---
# User File Uploads
-Images attached to issues, merge requests or comments do not require authentication
-to be viewed if someone knows the direct URL. This direct URL contains a random
-32-character ID that prevents unauthorized people from guessing the URL to an
-image containing sensitive information. We don't enable authentication because
-these images need to be visible in the body of notification emails, which are
-often read from email clients that are not authenticated with GitLab, like
-Outlook, Apple Mail, or the Mail app on your mobile device.
+Images that are attached to issues, merge requests, or comments
+do not require authentication to be viewed if they are accessed directly by URL.
+This direct URL contains a random 32-character ID that prevents unauthorized
+people from guessing the URL for an image, thus there is some protection if an
+image contains sensitive information.
-Note that non-image attachments do require authentication to be viewed.
+Authentication is not enabled because images must be visible in the body of
+notification emails, which are often read from email clients that are not
+authenticated with GitLab, such as Outlook, Apple Mail, or the Mail app on your
+mobile device.
+
+>**Note:**
+Non-image attachments do require authentication to be viewed.
+
+<!-- ## Troubleshooting
+
+Include any troubleshooting steps that you can foresee. If you know beforehand what issues
+one might have when setting this up, or when something is changed, or on upgrading, it's
+important to describe those, too. Think of things that may go wrong and include them here.
+This is important to minimize requests for support, and to avoid doc comments with
+questions that you know someone might ask.
+
+Each scenario can be a third-level heading, e.g. `### Getting error message X`.
+If you have none to add when creating a doc, leave this section in place
+but commented out to help encourage others to add to it in the future. -->
diff --git a/doc/security/webhooks.md b/doc/security/webhooks.md
index 8c26bbac6a7..d4fa088cb15 100644
--- a/doc/security/webhooks.md
+++ b/doc/security/webhooks.md
@@ -1,20 +1,56 @@
+---
+type: concepts, reference, howto
+---
# Webhooks and insecure internal web services
-If you have non-GitLab web services running on your GitLab server or within its local network, these may be vulnerable to exploitation via Webhooks.
+If you have non-GitLab web services running on your GitLab server or within its
+local network, these may be vulnerable to exploitation via Webhooks.
-With [Webhooks](../user/project/integrations/webhooks.md), you and your project maintainers and owners can set up URLs to be triggered when specific things happen to projects. Normally, these requests are sent to external web services specifically set up for this purpose, that process the request and its attached data in some appropriate way.
+With [Webhooks](../user/project/integrations/webhooks.md), you and your project
+maintainers and owners can set up URLs to be triggered when specific changes
+occur in your projects. Normally, these requests are sent to external web services
+specifically set up for this purpose, that process the request and its attached
+data in some appropriate way.
-Things get hairy, however, when a Webhook is set up with a URL that doesn't point to an external, but to an internal service, that may do something completely unintended when the webhook is triggered and the POST request is sent.
+Things get hairy, however, when a Webhook is set up with a URL that doesn't
+point to an external, but to an internal service, that may do something
+completely unintended when the webhook is triggered and the POST request is
+sent.
-Because Webhook requests are made by the GitLab server itself, these have complete access to everything running on the server (`http://localhost:123`) or within the server's local network (`http://192.168.1.12:345`), even if these services are otherwise protected and inaccessible from the outside world.
+Because Webhook requests are made by the GitLab server itself, these have
+complete access to everything running on the server (`http://localhost:123`) or
+within the server's local network (`http://192.168.1.12:345`), even if these
+services are otherwise protected and inaccessible from the outside world.
-If a web service does not require authentication, Webhooks can be used to trigger destructive commands by getting the GitLab server to make POST requests to endpoints like `http://localhost:123/some-resource/delete`.
+If a web service does not require authentication, Webhooks can be used to
+trigger destructive commands by getting the GitLab server to make POST requests
+to endpoints like `http://localhost:123/some-resource/delete`.
-To prevent this type of exploitation from happening, starting with GitLab 10.6, all Webhook requests to the current GitLab instance server address and/or in a private network will be forbidden by default. That means that all requests made to 127.0.0.1, ::1 and 0.0.0.0, as well as IPv4 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16 and IPv6 site-local (ffc0::/10) addresses won't be allowed.
+To prevent this type of exploitation from happening, starting with GitLab 10.6,
+all Webhook requests to the current GitLab instance server address and/or in a
+private network will be forbidden by default. That means that all requests made
+to 127.0.0.1, ::1 and 0.0.0.0, as well as IPv4 10.0.0.0/8, 172.16.0.0/12,
+192.168.0.0/16 and IPv6 site-local (ffc0::/10) addresses won't be allowed.
-This behavior can be overridden by enabling the option *"Allow requests to the local network from hooks and services"* in the *"Outbound requests"* section inside the Admin area under **Settings** (`/admin/application_settings/network`):
+This behavior can be overridden by enabling the option *"Allow requests to the
+local network from hooks and services"* in the *"Outbound requests"* section
+inside the Admin area under **Settings**
+(`/admin/application_settings/network`):
![Outbound requests admin settings](img/outbound_requests_section.png)
>**Note:**
-*System hooks* are exempt from this protection because they are set up by admins.
+*System hooks* are exempt from this protection because they are set up by
+admins.
+
+<!-- ## Troubleshooting
+
+Include any troubleshooting steps that you can foresee. If you know beforehand what issues
+one might have when setting this up, or when something is changed, or on upgrading, it's
+important to describe those, too. Think of things that may go wrong and include them here.
+This is important to minimize requests for support, and to avoid doc comments with
+questions that you know someone might ask.
+
+Each scenario can be a third-level heading, e.g. `### Getting error message X`.
+If you have none to add when creating a doc, leave this section in place
+but commented out to help encourage others to add to it in the future. -->
diff --git a/doc/ssh/README.md b/doc/ssh/README.md
index 3bfebfc5d9b..09b5fbd9260 100644
--- a/doc/ssh/README.md
+++ b/doc/ssh/README.md
@@ -1,3 +1,7 @@
+---
+type: howto, reference
+---
+
# GitLab and SSH keys
Git is a distributed version control system, which means you can work locally
@@ -50,8 +54,7 @@ more information, you can read this
We'll focus on ED25519 and RSA and here.
NOTE: **Note:**
-As an admin, you can restrict
-[which keys should be permitted and their minimum length](../security/ssh_keys_restrictions.md).
+As an admin, you can [restrict which keys should be permitted and their minimum length](../security/ssh_keys_restrictions.md).
By default, all keys are permitted, which is also the case for
[GitLab.com](../user/gitlab_com/index.md#ssh-host-keys-fingerprints).
@@ -91,9 +94,8 @@ ssh-keygen -o -f ~/.ssh/id_rsa
## Generating a new SSH key pair
-Before creating an SSH key pair, make sure to read about the
-[different types of keys](#types-of-ssh-keys-and-which-to-choose) to understand
-their differences.
+Before creating an SSH key pair, make sure to understand the
+[different types of keys](#types-of-ssh-keys-and-which-to-choose).
To create a new SSH key pair:
@@ -332,7 +334,7 @@ not implicitly give any access just by setting them up.
### Eclipse
-How to add your SSH key to Eclipse: <https://wiki.eclipse.org/EGit/User_Guide#Eclipse_SSH_Configuration>
+If you are using [EGit](https://www.eclipse.org/egit/), you can [add your SSH key to Eclipse](https://wiki.eclipse.org/EGit/User_Guide#Eclipse_SSH_Configuration).
## SSH on the GitLab server
diff --git a/doc/subscriptions/index.md b/doc/subscriptions/index.md
index dfd80f8882e..37051f6b10f 100644
--- a/doc/subscriptions/index.md
+++ b/doc/subscriptions/index.md
@@ -1,3 +1,7 @@
+---
+type: index, reference
+---
+
# Subscription setup and management
This page will help get you started with your new subscription or manage an existing one, whether you have subscribed to GitLab.com or self-managed GitLab.
@@ -42,7 +46,8 @@ After purchase, the license file is sent to the email address tied to the Custom
### Link your GitLab.com account with your Customers Portal account
-NOTE: **Note:** This is *required* for GitLab.com subscriptions.
+NOTE: **Note:**
+This is *required* for GitLab.com subscriptions.
Once signed into the customers portal, if your account is not already linked, you should be prompted to link your account with a "Link my GitLab Account" button.
@@ -87,6 +92,14 @@ plan - in the included table:
| Subscription start date | The date your subscription started. If this is for a Free plan, this is the date you transitioned off your group's paid plan. |
| Subscription end date | The date your current subscription will end. This does not apply to Free plans. |
+### Subscription changes and your data
+
+When your subscription or trial expires, GitLab does not delete your data, however, depending on the tier and feature, it may become inaccessible. Please note that some features may not behave as expected if a graceful fallback is not currently implemented, such as [environment specific variables not being passed](https://gitlab.com/gitlab-org/gitlab-ce/issues/52825).
+
+If you renew or upgrade, your data will again be accessible.
+
+For self-managed customers, there is a two-week grace period when your features will continue to work as-is, after which the entire instance will become read only. However, if you remove the license, you will immediately revert to Core features.
+
## Need help?
[GitLab's Documentation](https://docs.gitlab.com/) offers a wide range of topics covering the use and administration of GitLab.
@@ -101,3 +114,15 @@ These issues are the best avenue for getting updates on specific product plans a
### Contacting Support
Learn more about the tiers of [GitLab Support](https://about.gitlab.com/support/) or [submit a request via the Support Portal](https://support.gitlab.com/hc/en-us/requests/new).
+
+<!-- ## Troubleshooting
+
+Include any troubleshooting steps that you can foresee. If you know beforehand what issues
+one might have when setting this up, or when something is changed, or on upgrading, it's
+important to describe those, too. Think of things that may go wrong and include them here.
+This is important to minimize requests for support, and to avoid doc comments with
+questions that you know someone might ask.
+
+Each scenario can be a third-level heading, e.g. `### Getting error message X`.
+If you have none to add when creating a doc, leave this section in place
+but commented out to help encourage others to add to it in the future. -->
diff --git a/doc/system_hooks/system_hooks.md b/doc/system_hooks/system_hooks.md
index a3698d60f6d..a46f7d30892 100644
--- a/doc/system_hooks/system_hooks.md
+++ b/doc/system_hooks/system_hooks.md
@@ -1,3 +1,7 @@
+---
+type: reference
+---
+
# System hooks
Your GitLab instance can perform HTTP POST requests on the following events:
@@ -27,11 +31,9 @@ The triggers for most of these are self-explanatory, but `project_update` and `p
System hooks can be used, e.g. for logging or changing information in a LDAP server.
-> **Note:**
->
-> We follow the same structure from Webhooks for Push and Tag events, but we never display commits.
->
-> Same deprecations from Webhooks are valid here.
+NOTE: **Note:**
+We follow the same structure and deprecations as [Webhooks](../user/project/integrations/webhooks.md)
+for Push and Tag events, but we never display commits.
## Hooks request example
@@ -640,3 +642,15 @@ X-Gitlab-Event: System Hook
"refs":["refs/heads/master"]
}
```
+
+<!-- ## Troubleshooting
+
+Include any troubleshooting steps that you can foresee. If you know beforehand what issues
+one might have when setting this up, or when something is changed, or on upgrading, it's
+important to describe those, too. Think of things that may go wrong and include them here.
+This is important to minimize requests for support, and to avoid doc comments with
+questions that you know someone might ask.
+
+Each scenario can be a third-level heading, e.g. `### Getting error message X`.
+If you have none to add when creating a doc, leave this section in place
+but commented out to help encourage others to add to it in the future. -->
diff --git a/doc/tools/email.md b/doc/tools/email.md
index ab39206ffa4..a2d677484f0 100644
--- a/doc/tools/email.md
+++ b/doc/tools/email.md
@@ -1,12 +1,12 @@
-# Email from GitLab **[STARTER ONLY]**
-
-As a GitLab administrator you can email GitLab users from within GitLab.
+---
+type: howto, reference
+---
-## Overview
+# Email from GitLab **[STARTER ONLY]**
-GitLab provides a simple tool to email all users or users of a chosen group or
-project right from the admin area. Users will receive the email to their primary
-email address.
+GitLab provides a simple tool to administrators for emailing all users, or users of
+a chosen group or project, right from the admin area. Users will receive the email
+at their primary email address.
## Use-cases
@@ -28,11 +28,21 @@ email address.
## Unsubscribing from emails
-User can choose to unsubscribe from receiving emails from GitLab by following
-the unsubscribe link from the email. Unsubscribing is unauthenticated in order
-to keep the simplicity of this feature.
+Users can choose to unsubscribe from receiving emails from GitLab by following
+the unsubscribe link in the email. Unsubscribing is unauthenticated in order
+to keep this feature simple.
-On unsubscribe, user will receive an email notifying that unsubscribe happened.
+On unsubscribe, users will receive an email notification that unsubscribe happened.
The endpoint that provides the unsubscribe option is rate-limited.
-[ee]: https://about.gitlab.com/pricing/
+<!-- ## Troubleshooting
+
+Include any troubleshooting steps that you can foresee. If you know beforehand what issues
+one might have when setting this up, or when something is changed, or on upgrading, it's
+important to describe those, too. Think of things that may go wrong and include them here.
+This is important to minimize requests for support, and to avoid doc comments with
+questions that you know someone might ask.
+
+Each scenario can be a third-level heading, e.g. `### Getting error message X`.
+If you have none to add when creating a doc, leave this section in place
+but commented out to help encourage others to add to it in the future. -->
diff --git a/doc/topics/autodevops/index.md b/doc/topics/autodevops/index.md
index b00a8afa386..34140a3260e 100644
--- a/doc/topics/autodevops/index.md
+++ b/doc/topics/autodevops/index.md
@@ -8,7 +8,16 @@ to simplify the setup and execution of a mature & modern software development li
## Overview
-NOTE: **Enabled by default:**
+With Auto DevOps, the software development process becomes easier to set up
+as every project can have a complete workflow from verification to monitoring
+with minimal configuration. Just push your code and GitLab takes
+care of everything else. This makes it easier to start new projects and brings
+consistency to how applications are set up throughout a company.
+
+For an introduction to Auto DevOps, watch [AutoDevOps in GitLab 11.0](https://youtu.be/0Tc0YYBxqi4).
+
+## Enabled by default
+
Starting with GitLab 11.3, the Auto DevOps pipeline is enabled by default for all
projects. If it has not been explicitly enabled for the project, Auto DevOps will be automatically
disabled on the first pipeline failure. Your project will continue to use an alternative
@@ -16,12 +25,6 @@ disabled on the first pipeline failure. Your project will continue to use an alt
administrator can [change this setting](../../user/admin_area/settings/continuous_integration.md#auto-devops-core-only)
in the admin area.
-With Auto DevOps, the software development process becomes easier to set up
-as every project can have a complete workflow from verification to monitoring
-with minimal configuration. Just push your code and GitLab takes
-care of everything else. This makes it easier to start new projects and brings
-consistency to how applications are set up throughout a company.
-
## Quick start
If you are using GitLab.com, see the [quick start guide](quick_start_guide.md)
@@ -62,7 +65,7 @@ project in a simple and automatic way:
1. [Auto SAST (Static Application Security Testing)](#auto-sast-ultimate) **[ULTIMATE]**
1. [Auto Dependency Scanning](#auto-dependency-scanning-ultimate) **[ULTIMATE]**
1. [Auto License Management](#auto-license-management-ultimate) **[ULTIMATE]**
-1. [Auto Container Scanning](#auto-container-scanning)
+1. [Auto Container Scanning](#auto-container-scanning-ultimate) **[ULTIMATE]**
1. [Auto Review Apps](#auto-review-apps)
1. [Auto DAST (Dynamic Application Security Testing)](#auto-dast-ultimate) **[ULTIMATE]**
1. [Auto Deploy](#auto-deploy)
@@ -120,7 +123,6 @@ To make full use of Auto DevOps, you will need:
[default service template](../../user/project/integrations/services_templates.md)
for the entire GitLab installation.
-NOTE: **Note:**
If you do not have Kubernetes or Prometheus installed, then Auto Review Apps,
Auto Deploy, and Auto Monitoring will be silently skipped.
@@ -135,10 +137,13 @@ in any of the following places:
- or at the project level as a variable: `KUBE_INGRESS_BASE_DOMAIN`
- or at the group level as a variable: `KUBE_INGRESS_BASE_DOMAIN`.
-NOTE: **Note**
-The Auto DevOps base domain variable (`KUBE_INGRESS_BASE_DOMAIN`) follows the same order of precedence
+The base domain variable `KUBE_INGRESS_BASE_DOMAIN` follows the same order of precedence
as other environment [variables](../../ci/variables/README.md#priority-of-environment-variables).
+NOTE: **Note**
+`AUTO_DEVOPS_DOMAIN` environment variable is deprecated and
+[is scheduled to be removed](https://gitlab.com/gitlab-org/gitlab-ce/issues/56959).
+
A wildcard DNS A record matching the base domain(s) is required, for example,
given a base domain of `example.com`, you'd need a DNS entry like:
@@ -222,19 +227,20 @@ can enable/disable Auto DevOps at either the project-level or instance-level.
### Enabling/disabling Auto DevOps at the instance-level (Administrators only)
+Even when disabled at the instance level, group owners and project maintainers can still enable
+Auto DevOps at the group and project level, respectively.
+
1. Go to **Admin area > Settings > Continuous Integration and Deployment**.
1. Toggle the checkbox labeled **Default to Auto DevOps pipeline for all projects**.
1. If enabling, optionally set up the Auto DevOps [base domain](#auto-devops-base-domain) which will be used for Auto Deploy and Auto Review Apps.
1. Click **Save changes** for the changes to take effect.
-NOTE: **Note:**
-Even when disabled at the instance level, group owners and project maintainers are still able to enable
-Auto DevOps at group-level and project-level, respectively.
-
### Enabling/disabling Auto DevOps at the group-level
> [Introduced](https://gitlab.com/gitlab-org/gitlab-ce/issues/52447) in GitLab 11.10.
+Only administrators and group owners can enable or disable Auto DevOps at the group level.
+
To enable or disable Auto DevOps at the group-level:
1. Go to group's **Settings > CI/CD > Auto DevOps** page.
@@ -245,9 +251,6 @@ When enabling or disabling Auto DevOps at group-level, group configuration will
the subgroups and projects inside that group, unless Auto DevOps is specifically enabled or disabled on
the subgroup or project.
-NOTE: **Note**
-Only administrators and group owners are allowed to enable or disable Auto DevOps at group-level.
-
### Enabling/disabling Auto DevOps at the project-level
If enabling, check that your project doesn't have a `.gitlab-ci.yml`, or if one exists, remove it.
@@ -261,16 +264,13 @@ If enabling, check that your project doesn't have a `.gitlab-ci.yml`, or if one
When the feature has been enabled, an Auto DevOps pipeline is triggered on the default branch.
-NOTE: **Note:**
-For GitLab versions 10.0 - 10.2, when enabling Auto DevOps, a pipeline needs to be
-manually triggered either by pushing a new commit to the repository or by visiting
-`https://example.gitlab.com/<username>/<project>/pipelines/new` and creating
-a new pipeline for your default branch, generally `master`.
+### Feature flag to enable for a percentage of projects
-NOTE: **Note:**
-There is also a feature flag to enable Auto DevOps to a percentage of projects
-which can be enabled from the console with
-`Feature.get(:force_autodevops_on_by_default).enable_percentage_of_actors(10)`.
+There is also a feature flag to enable Auto DevOps by default to your chosen percentage of projects.
+
+This can be enabled from the console with the following, which uses the example of 10%:
+
+`Feature.get(:force_autodevops_on_by_default).enable_percentage_of_actors(10)`
### Deployment strategy
@@ -350,7 +350,6 @@ frameworks are detected automatically, but if your language is not detected,
you may succeed with a [custom buildpack](#custom-buildpacks). Check the
[currently supported languages](#currently-supported-languages).
-NOTE: **Note:**
Auto Test uses tests you already have in your application. If there are no
tests, it's up to you to add them.
@@ -371,73 +370,66 @@ Any differences between the source and target branches are also
Static Application Security Testing (SAST) uses the
[SAST Docker image](https://gitlab.com/gitlab-org/security-products/sast) to run static
-analysis on the current code and checks for potential security issues. Once the
-report is created, it's uploaded as an artifact which you can later download and
+analysis on the current code and checks for potential security issues. The
+the Auto SAST stage will be skipped on licenses other than Ultimate and requires GitLab Runner 11.5 or above.
+
+Once the report is created, it's uploaded as an artifact which you can later download and
check out.
Any security warnings are also shown in the merge request widget. Read more how
[SAST works](../../user/application_security/sast/index.md).
-NOTE: **Note:**
-The Auto SAST stage will be skipped on licenses other than Ultimate.
-
-NOTE: **Note:**
-The Auto SAST job requires GitLab Runner 11.5 or above.
-
### Auto Dependency Scanning **[ULTIMATE]**
> Introduced in [GitLab Ultimate][ee] 10.7.
Dependency Scanning uses the
[Dependency Scanning Docker image](https://gitlab.com/gitlab-org/security-products/dependency-scanning)
-to run analysis on the project dependencies and checks for potential security issues. Once the
+to run analysis on the project dependencies and checks for potential security issues.
+The Auto Dependency Scanning stage will be skipped on licenses other than Ultimate
+and requires GitLab Runner 11.5 or above.
+
+Once the
report is created, it's uploaded as an artifact which you can later download and
check out.
Any security warnings are also shown in the merge request widget. Read more about
[Dependency Scanning](../../user/application_security/dependency_scanning/index.md).
-NOTE: **Note:**
-The Auto Dependency Scanning stage will be skipped on licenses other than Ultimate.
-
-NOTE: **Note:**
-The Auto Dependency Scanning job requires GitLab Runner 11.5 or above.
-
### Auto License Management **[ULTIMATE]**
> Introduced in [GitLab Ultimate][ee] 11.0.
License Management uses the
[License Management Docker image](https://gitlab.com/gitlab-org/security-products/license-management)
-to search the project dependencies for their license. Once the
+to search the project dependencies for their license. The Auto License Management stage
+will be skipped on licenses other than Ultimate.
+
+Once the
report is created, it's uploaded as an artifact which you can later download and
check out.
Any licenses are also shown in the merge request widget. Read more how
[License Management works](../../user/application_security/license_management/index.md).
-NOTE: **Note:**
-The Auto License Management stage will be skipped on licenses other than Ultimate.
-
-### Auto Container Scanning
+### Auto Container Scanning **[ULTIMATE]**
> Introduced in GitLab 10.4.
Vulnerability Static Analysis for containers uses
[Clair](https://github.com/coreos/clair) to run static analysis on a
-Docker image and checks for potential security issues. Once the report is
+Docker image and checks for potential security issues. The Auto Container Scanning stage
+will be skipped on licenses other than Ultimate.
+
+Once the report is
created, it's uploaded as an artifact which you can later download and
check out.
Any security warnings are also shown in the merge request widget. Read more how
[Container Scanning works](../../user/application_security/container_scanning/index.md).
-NOTE: **Note:**
-The Auto Container Scanning stage will be skipped on licenses other than Ultimate.
-
### Auto Review Apps
-NOTE: **Note:**
This is an optional step, since many projects do not have a Kubernetes cluster
available. If the [requirements](#requirements) are not met, the job will
silently be skipped.
@@ -482,15 +474,14 @@ in the first place, and thus not realize that it needs to re-apply the old confi
Dynamic Application Security Testing (DAST) uses the
popular open source tool [OWASP ZAProxy](https://github.com/zaproxy/zaproxy)
to perform an analysis on the current code and checks for potential security
-issues. Once the report is created, it's uploaded as an artifact which you can
+issues. The Auto DAST stage will be skipped on licenses other than Ultimate.
+
+Once the report is created, it's uploaded as an artifact which you can
later download and check out.
Any security warnings are also shown in the merge request widget. Read how
[DAST works](../../user/application_security/dast/index.md).
-NOTE: **Note:**
-The Auto DAST stage will be skipped on licenses other than Ultimate.
-
### Auto Browser Performance Testing **[PREMIUM]**
> Introduced in [GitLab Premium][ee] 10.4.
@@ -508,7 +499,6 @@ Any performance differences between the source and target branches are also
### Auto Deploy
-NOTE: **Note:**
This is an optional step, since many projects do not have a Kubernetes cluster
available. If the [requirements](#requirements) are not met, the job will
silently be skipped.
@@ -547,7 +537,7 @@ in the first place, and thus not realize that it needs to re-apply the old confi
For internal and private projects a [GitLab Deploy Token](../../user/project/deploy_tokens/index.md#gitlab-deploy-token)
will be automatically created, when Auto DevOps is enabled and the Auto DevOps settings are saved. This Deploy Token
-can be used for permanent access to the registry.
+can be used for permanent access to the registry. When the GitLab Deploy Token has been manually revoked, it won't be automatically created.
If the GitLab Deploy Token cannot be found, `CI_REGISTRY_PASSWORD` is
used. Note that `CI_REGISTRY_PASSWORD` is only valid during deployment.
@@ -557,9 +547,6 @@ be pulled again, e.g. after pod eviction, Kubernetes will fail to do so
as it will be attempting to fetch the image using
`CI_REGISTRY_PASSWORD`.
-NOTE: **Note:**
-When the GitLab Deploy Token has been manually revoked, it won't be automatically created.
-
#### Migrations
> [Introduced][ce-21955] in GitLab 11.4
@@ -588,17 +575,13 @@ For example, in a Rails application in an image built with
- `DB_INITIALIZE` can be set to `RAILS_ENV=production /bin/herokuish procfile exec bin/rails db:setup`
- `DB_MIGRATE` can be set to `RAILS_ENV=production /bin/herokuish procfile exec bin/rails db:migrate`
-NOTE: **Note:**
Unless you have a `Dockerfile` in your repo, your image is built with
-Herokuish. You must prefix commands run in these images with `/bin/herokuish
-procfile exec` in order to replicate the the environment your application is
-run in.
+Herokuish, and you must prefix commands run in these images with `/bin/herokuish
+procfile exec` to replicate the environment where your application will run.
### Auto Monitoring
-NOTE: **Note:**
-Check the [requirements](#requirements) for Auto Monitoring to make this stage
-work.
+See the [requirements](#requirements) for Auto Monitoring to enable this stage.
Once your application is deployed, Auto Monitoring makes it possible to monitor
your application's server and response metrics right out of the box. Auto
@@ -826,11 +809,6 @@ metadata:
type: Opaque
```
-CAUTION: **Caution:**
-Variables with multiline values are not currently supported due to
-limitations with the current Auto DevOps scripting environment.
-
-NOTE: **Note:**
Environment variables are generally considered immutable in a Kubernetes
pod. Therefore, if you update an application secret without changing any
code then manually create a new pipeline, you will find that any running
@@ -839,6 +817,10 @@ can either push a code update to GitLab to force the Kubernetes
Deployment to recreate pods or manually delete running pods to
cause Kubernetes to create new pods with updated secrets.
+NOTE: **Note:**
+Variables with multiline values are not currently supported due to
+limitations with the current Auto DevOps scripting environment.
+
#### Advanced replica variables setup
Apart from the two replica-related variables for production mentioned above,
@@ -1007,8 +989,7 @@ Everything behaves the same way, except:
## Currently supported languages
-NOTE: **Note:**
-Not all buildpacks support Auto Test yet, as it's a relatively new
+Note that not all buildpacks support Auto Test yet, as it's a relatively new
enhancement. All of Heroku's [officially supported
languages](https://devcenter.heroku.com/articles/heroku-ci#currently-supported-languages)
support it, and some third-party buildpacks as well e.g., Go, Node, Java, PHP,
diff --git a/doc/topics/autodevops/quick_start_guide.md b/doc/topics/autodevops/quick_start_guide.md
index cc83d20d65a..6717e95266e 100644
--- a/doc/topics/autodevops/quick_start_guide.md
+++ b/doc/topics/autodevops/quick_start_guide.md
@@ -161,7 +161,7 @@ In the **test** stage, GitLab runs various checks on the application:
- The `code_quality` job checks the code quality and is allowed to fail
([Auto Code Quality](index.md#auto-code-quality-starter)) **[STARTER]**
- The `container_scanning` job checks the Docker container if it has any
- vulnerabilities and is allowed to fail ([Auto Container Scanning](index.md#auto-container-scanning))
+ vulnerabilities and is allowed to fail ([Auto Container Scanning](index.md#auto-container-scanning-ultimate))
- The `dependency_scanning` job checks if the application has any dependencies
susceptible to vulnerabilities and is allowed to fail ([Auto Dependency Scanning](index.md#auto-dependency-scanning-ultimate)) **[ULTIMATE]**
- The `sast` job runs static analysis on the current code to check for potential
diff --git a/doc/topics/git/index.md b/doc/topics/git/index.md
index 841746cc5de..cdcd8215b23 100644
--- a/doc/topics/git/index.md
+++ b/doc/topics/git/index.md
@@ -21,6 +21,8 @@ More information is also available on the [Git website](https://git-scm.com).
The following resources will help you get started with Git:
+- [Git-ing started with Git](https://www.youtube.com/watch?v=Ce5nz5n41z4),
+ a video introduction to Git.
- [Git Basics](https://git-scm.com/book/en/v2/Getting-Started-Git-Basics)
- [Git on the Server - GitLab](https://git-scm.com/book/en/v2/Git-on-the-Server-GitLab)
- [How to install Git](how_to_install_git/index.md)
diff --git a/doc/university/README.md b/doc/university/README.md
index 61ed72d25fb..c116e54ad48 100644
--- a/doc/university/README.md
+++ b/doc/university/README.md
@@ -1,5 +1,6 @@
---
comments: false
+type: index
---
# GitLab University
@@ -8,26 +9,22 @@ GitLab University is a great place to start when learning about version control
If you're looking for a GitLab subscription for _your university_, see our [Education](https://about.gitlab.com/solutions/education/) page.
-## GitLab University Curriculum
+The GitLab University 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:
-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.
+1. [GitLab Beginner](#1-gitlab-beginner).
+1. [GitLab Intermediate](#2-gitlab-intermediate).
+1. [GitLab Advanced](#3-gitlab-advanced).
+1. [External Articles](#4-external-articles).
+1. [Resources for GitLab Team Members](#5-resources-for-gitlab-team-members).
-1. [GitLab Beginner](#1-gitlab-beginner)
-1. [GitLab Intermediate](#2-gitlab-intermediate)
-1. [GitLab Advanced](#3-gitlab-advanced)
-1. [External Articles](#4-external-articles)
-1. [Resources for GitLab Team Members](#5-resources-for-gitlab-team-members)
+## 1. GitLab Beginner
----
-
-### 1. GitLab Beginner
-
-#### 1.1. Version Control and Git
+### 1.1. Version Control and Git
1. [Version Control Systems](https://docs.google.com/presentation/d/16sX7hUrCZyOFbpvnrAFrg6tVO5_yT98IgdAqOmXwBho/edit#slide=id.g72f2e4906_2_29)
1. [Code School: An Introduction to Git](https://www.codeschool.com/account/courses/try-git)
-#### 1.2. GitLab Basics
+### 1.2. GitLab Basics
1. [An Overview of GitLab.com - Video](https://www.youtube.com/watch?v=WaiL5DGEMR4)
1. [Why Use Git and GitLab - Slides](https://docs.google.com/a/gitlab.com/presentation/d/1RcZhFmn5VPvoFu6UMxhMOy7lAsToeBZRjLRn0LIdaNc/edit?usp=drive_web)
@@ -36,12 +33,12 @@ The curriculum is composed of GitLab videos, screencasts, presentations, project
1. [Git and GitLab Basics - Online Course](https://courses.platzi.com/classes/git-gitlab/concepto/part-1/part-23370/material/)
1. [Comparison of GitLab Versions](https://about.gitlab.com/features/#compare)
-#### 1.3. Your GitLab Account
+### 1.3. Your GitLab Account
1. [Create a GitLab Account - Online Course](https://courses.platzi.com/classes/git-gitlab/concepto/first-steps/create-an-account-on-gitlab/material/)
1. [Create and Add your SSH key to GitLab - Video](https://www.youtube.com/watch?v=54mxyLo3Mqk)
-#### 1.4. GitLab Projects
+### 1.4. GitLab Projects
1. [Repositories, Projects and Groups - Video](https://www.youtube.com/watch?v=4TWfh1aKHHw&index=1&list=PLFGfElNsQthbQu_IWlNOxul0TbS_2JH-e)
1. [Creating a Project in GitLab - Video](https://www.youtube.com/watch?v=7p0hrpNaJ14)
@@ -49,14 +46,14 @@ The curriculum is composed of GitLab videos, screencasts, presentations, project
1. [GitLab Todos](https://about.gitlab.com/2016/03/02/gitlab-todos-feature-highlight/)
1. [GitLab's Work in Progress (WIP) Flag](https://about.gitlab.com/2016/01/08/feature-highlight-wip/)
-#### 1.5. Migrating from other Source Control
+### 1.5. Migrating from other Source Control
1. [Migrating from BitBucket/Stash](../user/project/import/bitbucket.md)
1. [Migrating from GitHub](../user/project/import/github.md)
1. [Migrating from SVN](../user/project/import/svn.md)
1. [Migrating from Fogbugz](../user/project/import/fogbugz.md)
-#### 1.6. GitLab Inc.
+### 1.6. GitLab Inc.
1. [About GitLab](https://about.gitlab.com/about/)
1. [GitLab Direction](https://about.gitlab.com/direction/)
@@ -67,7 +64,7 @@ The curriculum is composed of GitLab videos, screencasts, presentations, project
1. [The GitLab Book Club](bookclub/index.md)
1. [GitLab Resources](https://about.gitlab.com/resources/)
-#### 1.7 Community and Support
+### 1.7 Community and Support
1. [Getting Help](https://about.gitlab.com/getting-help/)
- Proposing Features and Reporting and Tracking bugs for GitLab
@@ -79,22 +76,19 @@ The curriculum is composed of GitLab videos, screencasts, presentations, project
1. [GitLab Training Workshops](https://docs.gitlab.com/ce/university/training/end-user/)
1. [GitLab Professional Services](https://about.gitlab.com/services/)
-#### 1.8 GitLab Training Material
+### 1.8 GitLab Training Material
-1. [Git and GitLab Terminology](glossary/README.md)
1. [Git and GitLab Workshop - Slides](https://docs.google.com/presentation/d/1JzTYD8ij9slejV2-TO-NzjCvlvj6mVn9BORePXNJoMI/edit?usp=drive_web)
----
-
-### 2. GitLab Intermediate
+## 2. GitLab Intermediate
-#### 2.1 GitLab Pages
+### 2.1 GitLab Pages
1. [Using any Static Site Generator with GitLab Pages](https://about.gitlab.com/2016/06/17/ssg-overview-gitlab-pages-part-3-examples-ci/)
1. [Securing GitLab Pages with SSL](https://about.gitlab.com/2016/06/24/secure-gitlab-pages-with-startssl/)
1. [GitLab Pages Documentation](../user/project/pages/index.md)
-#### 2.2. GitLab Issues
+### 2.2. GitLab Issues
1. [Markdown in GitLab](../user/markdown.md)
1. [Issues and Merge Requests - Video](https://www.youtube.com/watch?v=raXvuwet78M)
@@ -106,7 +100,7 @@ The curriculum is composed of GitLab videos, screencasts, presentations, project
1. [Designing GitLab Issue Board](https://about.gitlab.com/2016/08/31/designing-issue-boards/)
1. [From Idea to Production with GitLab - Video](https://www.youtube.com/watch?v=25pHyknRgEo&index=14&list=PLFGfElNsQthbQu_IWlNOxul0TbS_2JH-e)
-#### 2.3. Continuous Integration
+### 2.3. Continuous Integration
1. [Operating Systems, Servers, VMs, Containers and Unix - Video](https://www.youtube.com/watch?v=V61kL6IC-zY&index=8&list=PLFGfElNsQthbQu_IWlNOxul0TbS_2JH-e)
1. [GitLab CI - Product Page](https://about.gitlab.com/gitlab-ci/)
@@ -125,7 +119,7 @@ The curriculum is composed of GitLab videos, screencasts, presentations, project
1. [TechBeacon: Doing continuous delivery? Focus first on reducing release cycle times](https://techbeacon.com/doing-continuous-delivery-focus-first-reducing-release-cycle-times)
1. See **[Integrations](#39-integrations)** for integrations with other CI services.
-#### 2.4. Workflow
+### 2.4. Workflow
1. [GitLab Flow - Video](https://youtu.be/enMumwvLAug?list=PLFGfElNsQthZnwMUFi6rqkyUZkI00OxIV)
1. [GitLab Flow vs Forking in GitLab - Video](https://www.youtube.com/watch?v=UGotqAUACZA)
@@ -133,7 +127,7 @@ The curriculum is composed of GitLab videos, screencasts, presentations, project
1. [Always Start with an Issue](https://about.gitlab.com/2016/03/03/start-with-an-issue/)
1. [GitLab Flow Documentation](../workflow/gitlab_flow.md)
-#### 2.5. GitLab Comparisons
+### 2.5. GitLab Comparisons
1. [GitLab Compared to Other Tools](https://about.gitlab.com/comparison/)
1. [Comparing GitLab Terminology](https://about.gitlab.com/2016/01/27/comparing-terms-gitlab-github-bitbucket/)
@@ -141,17 +135,15 @@ The curriculum is composed of GitLab videos, screencasts, presentations, project
1. [GitLab Position FAQ](https://about.gitlab.com/handbook/positioning-faq)
1. [Customer review of GitLab with points on why they prefer GitLab](https://www.enovate.co.uk/web-design-blog/2015/11/25/gitlab-review/)
----
+## 3. GitLab Advanced
-### 3. GitLab Advanced
-
-#### 3.1. Dev Ops
+### 3.1. Dev Ops
1. [Xebia Labs: Dev Ops Terminology](https://xebialabs.com/glossary/)
1. [Xebia Labs: Periodic Table of DevOps Tools](https://xebialabs.com/periodic-table-of-devops-tools/)
1. [Puppet Labs: State of Dev Ops 2016 - Book](https://puppet.com/resources/white-paper/2016-state-of-devops-report)
-#### 3.2. Installing GitLab with Omnibus
+### 3.2. Installing GitLab with Omnibus
1. [What is Omnibus - Video](https://www.youtube.com/watch?v=XTmpKudd-Oo)
1. [How to Install GitLab with Omnibus - Video](https://www.youtube.com/watch?v=Q69YaOjqNhg)
@@ -161,34 +153,34 @@ The curriculum is composed of GitLab videos, screencasts, presentations, project
1. [Installing GitLab on Microsoft Azure](https://about.gitlab.com/2016/07/13/how-to-setup-a-gitlab-instance-on-microsoft-azure/)
1. [Installing GitLab on Digital Ocean](https://about.gitlab.com/2016/04/27/getting-started-with-gitlab-and-digitalocean/)
-#### 3.3. Permissions
+### 3.3. Permissions
1. [How to Manage Permissions in GitLab EE - Video](https://www.youtube.com/watch?v=DjUoIrkiNuM)
-#### 3.4. Large Files
+### 3.4. Large Files
1. [Big files in Git (Git LFS) - Video](https://www.youtube.com/watch?v=DawznUxYDe4)
-#### 3.5. LDAP and Active Directory
+### 3.5. LDAP and Active Directory
1. [How to Manage LDAP, Active Directory in GitLab - Video](https://www.youtube.com/watch?v=HPMjM-14qa8)
-#### 3.6 Custom Languages
+### 3.6 Custom Languages
1. [How to add Syntax Highlighting Support for Custom Languages to GitLab - Video](https://youtu.be/6WxTMqatrrA)
-#### 3.7. Scalability and High Availability
+### 3.7. Scalability and High Availability
1. [Scalability and High Availability - Video](https://www.youtube.com/watch?v=cXRMJJb6sp4&list=PLFGfElNsQthbQu_IWlNOxul0TbS_2JH-e&index=2)
1. [High Availability - Video](https://www.youtube.com/watch?v=36KS808u6bE&index=15&list=PLFGfElNsQthbQu_IWlNOxul0TbS_2JH-e)
1. [High Availability Documentation](https://about.gitlab.com/high-availability/)
-#### 3.8 Cycle Analytics
+### 3.8 Cycle Analytics
1. [GitLab Cycle Analytics Overview](https://about.gitlab.com/2016/09/21/cycle-analytics-feature-highlight/)
1. [GitLab Cycle Analytics - Product Page](https://about.gitlab.com/product/cycle-analytics/)
-#### 3.9. Integrations
+### 3.9. Integrations
1. [How to Integrate JIRA and Jenkins with GitLab - Video](https://gitlabmeetings.webex.com/gitlabmeetings/ldr.php?RCID=44b548147a67ab4d8a62274047146415)
1. [How to Integrate Jira with GitLab](../user/project/integrations/jira.md)
@@ -198,25 +190,21 @@ The curriculum is composed of GitLab videos, screencasts, presentations, project
1. [How to Integrate Convox with GitLab](https://about.gitlab.com/2016/06/09/continuous-delivery-with-gitlab-and-convox/)
1. [Getting Started with GitLab and Shippable CI](https://about.gitlab.com/2016/05/05/getting-started-gitlab-and-shippable/)
----
-
-### 4. External Articles
+## 4. External Articles
1. [2011 WSJ article by Marc Andreessen - Software is Eating the World](https://www.wsj.com/articles/SB10001424053111903480904576512250915629460)
1. [2014 Blog post by Chris Dixon - Software eats software development](http://cdixon.org/2014/04/13/software-eats-software-development/)
1. [2015 Venture Beat article - Actually, Open Source is Eating the World](http://venturebeat.com/2015/12/06/its-actually-open-source-software-thats-eating-the-world/)
----
-
-### 5. Resources for GitLab Team Members
+## 5. Resources for GitLab Team Members
NOTE: **Note:**
-Some content can only be accessed by GitLab team members
+Some content can only be accessed by GitLab team members.
1. [Support Path](support/README.md)
-1. [Sales Path (redirect to sales handbook)](https://about.gitlab.com/handbook/sales-onboarding/)
+1. [Sales Path](https://about.gitlab.com/handbook/sales-onboarding/)
1. [User Training](training/user_training.md)
1. [GitLab Flow Training](training/gitlab_flow.md)
-1. [Training Topics](https://gitlab.com/gitlab-org/gitlab-ce/tree/master/doc/university/training/topics/)
-1. [GitLab architecture for noobs](https://dev.gitlab.org/gitlab/gitlabhq/blob/master/doc/development/architecture.md)
+1. [Training Topics](training/index.md)
+1. [GitLab architecture](../development/architecture.md)
1. [Client Assessment of GitLab versus GitHub](https://docs.google.com/a/gitlab.com/spreadsheets/d/18cRF9Y5I6I7Z_ab6qhBEW55YpEMyU4PitZYjomVHM-M/edit?usp=sharing)
diff --git a/doc/university/bookclub/booklist.md b/doc/university/bookclub/booklist.md
index d5662be6fa6..33298e45393 100644
--- a/doc/university/bookclub/booklist.md
+++ b/doc/university/bookclub/booklist.md
@@ -1,117 +1,118 @@
---
comments: false
+type: index
---
# Books
-List of books and resources, that may be worth reading.
+List of books and resources that may be worth reading.
## Papers
-1. **The Humble Programmer**
+1. **The Humble Programmer**
- Edsger W. Dijkstra, 1972 ([paper](https://dl.acm.org/citation.cfm?id=361591))
+ Edsger W. Dijkstra, 1972 ([paper](https://dl.acm.org/citation.cfm?id=361591))
## Programming
-1. **Design Patterns: Elements of Reusable Object-Oriented Software**
+1. **Design Patterns: Elements of Reusable Object-Oriented Software**
- Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides, 1994 ([amazon](https://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612))
+ Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides, 1994 ([amazon](https://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612))
-1. **Clean Code: A Handbook of Agile Software Craftsmanship**
+1. **Clean Code: A Handbook of Agile Software Craftsmanship**
- Robert C. "Uncle Bob" Martin, 2008 ([amazon](https://www.amazon.com/Clean-Code-Handbook-Software-Craftsmanship/dp/0132350882))
+ Robert C. "Uncle Bob" Martin, 2008 ([amazon](https://www.amazon.com/Clean-Code-Handbook-Software-Craftsmanship/dp/0132350882))
-1. **Code Complete: A Practical Handbook of Software Construction**, 2nd Edition
+1. **Code Complete: A Practical Handbook of Software Construction**, 2nd Edition
- Steve McConnell, 2004 ([amazon](https://www.amazon.com/Code-Complete-Practical-Handbook-Construction/dp/0735619670))
+ Steve McConnell, 2004 ([amazon](https://www.amazon.com/Code-Complete-Practical-Handbook-Construction/dp/0735619670))
-1. **The Pragmatic Programmer: From Journeyman to Master**
+1. **The Pragmatic Programmer: From Journeyman to Master**
- Andrew Hunt, David Thomas, 1999 ([amazon](https://www.amazon.com/Pragmatic-Programmer-Journeyman-Master/dp/020161622X))
+ Andrew Hunt, David Thomas, 1999 ([amazon](https://www.amazon.com/Pragmatic-Programmer-Journeyman-Master/dp/020161622X))
-1. **Working Effectively with Legacy Code**
+1. **Working Effectively with Legacy Code**
- Michael Feathers, 2004 ([amazon](https://www.amazon.com/Working-Effectively-Legacy-Michael-Feathers/dp/0131177052))
+ Michael Feathers, 2004 ([amazon](https://www.amazon.com/Working-Effectively-Legacy-Michael-Feathers/dp/0131177052))
-1. **Eloquent Ruby**
+1. **Eloquent Ruby**
- Russ Olsen, 2011 ([amazon](https://www.amazon.com/Eloquent-Ruby-Addison-Wesley-Professional/dp/0321584104))
+ Russ Olsen, 2011 ([amazon](https://www.amazon.com/Eloquent-Ruby-Addison-Wesley-Professional/dp/0321584104))
-1. **Domain-Driven Design: Tackling Complexity in the Heart of Software**
+1. **Domain-Driven Design: Tackling Complexity in the Heart of Software**
- Eric Evans, 2003 ([amazon](https://www.amazon.com/Domain-Driven-Design-Tackling-Complexity-Software/dp/0321125215))
+ Eric Evans, 2003 ([amazon](https://www.amazon.com/Domain-Driven-Design-Tackling-Complexity-Software/dp/0321125215))
-1. **How to Solve It: A New Aspect of Mathematical Method**
+1. **How to Solve It: A New Aspect of Mathematical Method**
- Polya G. 1957 ([amazon](https://www.amazon.com/How-Solve-Mathematical-Princeton-Science/dp/069116407X))
+ Polya G. 1957 ([amazon](https://www.amazon.com/How-Solve-Mathematical-Princeton-Science/dp/069116407X))
-1. **Software Creativity 2.0**
+1. **Software Creativity 2.0**
- Robert L. Glass, 2006 ([amazon](https://www.amazon.com/Software-Creativity-2-0-Robert-Glass/dp/0977213315))
+ Robert L. Glass, 2006 ([amazon](https://www.amazon.com/Software-Creativity-2-0-Robert-Glass/dp/0977213315))
-1. **Object-Oriented Software Construction**
+1. **Object-Oriented Software Construction**
- Bertrand Meyer, 1997 ([amazon](https://www.amazon.com/Object-Oriented-Software-Construction-Book-CD-ROM/dp/0136291554))
+ Bertrand Meyer, 1997 ([amazon](https://www.amazon.com/Object-Oriented-Software-Construction-Book-CD-ROM/dp/0136291554))
-1. **Refactoring: Improving the Design of Existing Code**
+1. **Refactoring: Improving the Design of Existing Code**
- Martin Fowler, Kent Beck, 1999 ([amazon](https://www.amazon.com/Refactoring-Improving-Design-Existing-Code/dp/0201485672))
+ Martin Fowler, Kent Beck, 1999 ([amazon](https://www.amazon.com/Refactoring-Improving-Design-Existing-Code/dp/0201485672))
-1. **Test Driven Development: By Example**
+1. **Test Driven Development: By Example**
- Kent Beck, 2002 ([amazon](https://www.amazon.com/Test-Driven-Development-Kent-Beck/dp/0321146530))
+ Kent Beck, 2002 ([amazon](https://www.amazon.com/Test-Driven-Development-Kent-Beck/dp/0321146530))
-1. **Algorithms in C++: Fundamentals, Data Structure, Sorting, Searching**
+1. **Algorithms in C++: Fundamentals, Data Structure, Sorting, Searching**
- Robert Sedgewick, 1990 ([amazon](https://www.amazon.com/Algorithms-Parts-1-4-Fundamentals-Structure/dp/0201350882))
+ Robert Sedgewick, 1990 ([amazon](https://www.amazon.com/Algorithms-Parts-1-4-Fundamentals-Structure/dp/0201350882))
-1. **Effective C++**
+1. **Effective C++**
- Scott Mayers, 1996 ([amazon](https://www.amazon.com/Effective-Specific-Improve-Programs-Designs/dp/0321334876))
+ Scott Mayers, 1996 ([amazon](https://www.amazon.com/Effective-Specific-Improve-Programs-Designs/dp/0321334876))
-1. **Extreme Programming Explained: Embrace Change**
+1. **Extreme Programming Explained: Embrace Change**
- Kent Beck, 1999 ([amazon](https://www.amazon.com/Extreme-Programming-Explained-Embrace-Change/dp/0321278658))
+ Kent Beck, 1999 ([amazon](https://www.amazon.com/Extreme-Programming-Explained-Embrace-Change/dp/0321278658))
-1. **The Art of Computer Programming**
+1. **The Art of Computer Programming**
- Donald E. Knuth, 1997 ([amazon](https://www.amazon.com/Computer-Programming-Volumes-1-4A-Boxed/dp/0321751043))
+ Donald E. Knuth, 1997 ([amazon](https://www.amazon.com/Computer-Programming-Volumes-1-4A-Boxed/dp/0321751043))
-1. **Writing Efficient Programs**
+1. **Writing Efficient Programs**
- Jon Louis Bentley, 1982 ([amazon](https://www.amazon.com/Writing-Efficient-Programs-Prentice-Hall-Software/dp/013970244X))
+ Jon Louis Bentley, 1982 ([amazon](https://www.amazon.com/Writing-Efficient-Programs-Prentice-Hall-Software/dp/013970244X))
-1. **The Mythical Man-Month: Essays on Software Engineering**
+1. **The Mythical Man-Month: Essays on Software Engineering**
- Frederick Phillips Brooks, 1975 ([amazon](https://www.amazon.com/Mythical-Man-Month-Essays-Software-Engineering/dp/0201006502))
+ Frederick Phillips Brooks, 1975 ([amazon](https://www.amazon.com/Mythical-Man-Month-Essays-Software-Engineering/dp/0201006502))
-1. **Peopleware: Productive Projects and Teams** 3rd Edition
+1. **Peopleware: Productive Projects and Teams** 3rd Edition
- Tom DeMarco, Tim Lister, 2013 ([amazon](https://www.amazon.com/Peopleware-Productive-Projects-Teams-3rd/dp/0321934113))
+ Tom DeMarco, Tim Lister, 2013 ([amazon](https://www.amazon.com/Peopleware-Productive-Projects-Teams-3rd/dp/0321934113))
-1. **Principles Of Software Engineering Management**
+1. **Principles Of Software Engineering Management**
- Tom Gilb, 1988 ([amazon](https://www.amazon.com/Principles-Software-Engineering-Management-Gilb/dp/0201192462))
+ Tom Gilb, 1988 ([amazon](https://www.amazon.com/Principles-Software-Engineering-Management-Gilb/dp/0201192462))
## Other
-1. **Thinking, Fast and Slow**
+1. **Thinking, Fast and Slow**
- Daniel Kahneman, 2013 ([amazon](https://www.amazon.com/Thinking-Fast-Slow-Daniel-Kahneman/dp/0374533555))
+ Daniel Kahneman, 2013 ([amazon](https://www.amazon.com/Thinking-Fast-Slow-Daniel-Kahneman/dp/0374533555))
-1. **The Social Animal** 11th Edition
+1. **The Social Animal** 11th Edition
- Elliot Aronson, 2011 ([amazon](https://www.amazon.com/Social-Animal-Elliot-Aronson/dp/1429233419))
+ Elliot Aronson, 2011 ([amazon](https://www.amazon.com/Social-Animal-Elliot-Aronson/dp/1429233419))
-1. **Influence: Science and Practice** 5th Edition
+1. **Influence: Science and Practice** 5th Edition
- Robert B. Cialdini, 2008 ([amazon](https://www.amazon.com/Influence-Practice-Robert-B-Cialdini/dp/0205609996))
+ Robert B. Cialdini, 2008 ([amazon](https://www.amazon.com/Influence-Practice-Robert-B-Cialdini/dp/0205609996))
-1. **Getting to Yes: Negotiating Agreement Without Giving In**
+1. **Getting to Yes: Negotiating Agreement Without Giving In**
- Roger Fisher, William L. Ury, Bruce Patton, 2011 ([amazon](https://www.amazon.com/Getting-Yes-Negotiating-Agreement-Without/dp/0143118757))
+ Roger Fisher, William L. Ury, Bruce Patton, 2011 ([amazon](https://www.amazon.com/Getting-Yes-Negotiating-Agreement-Without/dp/0143118757))
-1. **How to Win Friends & Influence People**
+1. **How to Win Friends & Influence People**
- Dale Carnegie, 1981 ([amazon](https://www.amazon.com/How-Win-Friends-Influence-People/dp/0671027034))
+ Dale Carnegie, 1981 ([amazon](https://www.amazon.com/How-Win-Friends-Influence-People/dp/0671027034))
diff --git a/doc/university/bookclub/index.md b/doc/university/bookclub/index.md
index 63238685b2b..330078e979f 100644
--- a/doc/university/bookclub/index.md
+++ b/doc/university/bookclub/index.md
@@ -1,5 +1,6 @@
---
comments: false
+type: index
---
# The GitLab Book Club
@@ -11,13 +12,13 @@ See the [book list](booklist.md) for additional recommendations.
## Currently reading : Books about remote work
-1. **Remote: Office not required**
+1. **Remote: Office not required**
- David Heinemeier Hansson and Jason Fried, 2013
- ([amazon](http://www.amazon.co.uk/Remote-Required-David-Heinemeier-Hansson/dp/0091954673))
+ David Heinemeier Hansson and Jason Fried, 2013
+ ([amazon](http://www.amazon.co.uk/Remote-Required-David-Heinemeier-Hansson/dp/0091954673))
-1. **The Year Without Pants**
+1. **The Year Without Pants**
- Scott Berkun, 2013 ([ScottBerkun.com](http://scottberkun.com/yearwithoutpants/))
+ Scott Berkun, 2013 ([ScottBerkun.com](http://scottberkun.com/yearwithoutpants/))
Any other books you'd like to suggest? Edit this page and add them to the queue.
diff --git a/doc/university/glossary/README.md b/doc/university/glossary/README.md
index f15b0107de5..21e2da3e47c 100644
--- a/doc/university/glossary/README.md
+++ b/doc/university/glossary/README.md
@@ -2,707 +2,10 @@
comments: false
---
-# What is the Glossary
+# Glossary
-This contains a simplified list and definitions of some of the terms that you will encounter in your day to day activities when working with GitLab.
-Please add any terms that you discover that you think would be useful for others.
+This page has been removed after an effort to ensure that all applicable GitLab-specific
+terms are available in context on the relevant [GitLab Documentation](https://docs.gitlab.com/)
+or [about.gitlab.com](https://about.gitlab.com/) pages.
-### 2FA
-
-User authentication by combination of 2 different steps during login. This allows for [more security](https://about.gitlab.com/handbook/security/).
-
-### Access Levels
-
-Process of selective restriction to create, view, modify or delete a resource based on a set of assigned permissions. See [GitLab's Permission Guidelines](../../user/permissions.md)
-
-### Active Directory (AD)
-
-A Microsoft-based [directory service](https://msdn.microsoft.com/en-us/library/bb742424.aspx) for windows domain networks. It uses LDAP technology under the hood.
-
-### Agile
-
-Building and [delivering software](http://agilemethodology.org/) in phases/parts rather than trying to build everything at once then delivering to the user/client. The latter is known as the WaterFall model.
-
-### Amazon RDS
-
-External reference: <http://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/CHAP_Storage.html>
-
-### Application Lifecycle Management (ALM)
-
-The entire product lifecycle management process for an application, from requirements management, development, and testing until deployment. GitLab has [advantages](https://docs.google.com/presentation/d/1vCU-NbZWz8NTNK8Vu3y4zGMAHb5DpC8PE5mHtw1PWfI/edit#slide=id.g72f2e4906_2_288) over both legacy and modern ALM tools.
-
-### Artifactory
-
-A version control [system](https://www.jfrog.com/open-source/#os-arti) for non-text files.
-
-### Artifacts
-
-Objects (usually binary and large) created by a build process. These can include use cases, class diagrams, requirements and design documents.
-
-### Atlassian
-
-A [company](https://www.atlassian.com) that develops software products for developers and project managers including Bitbucket, Jira, Hipchat, Confluence, Bamboo.
-
-### Audit Log
-
-Also called an [audit trail](https://en.wikipedia.org/wiki/Audit_trail), an audit log is a document that records an event in an IT system.
-
-### Auto Defined User Group
-
-User groups are a way of centralizing control over important management tasks, particularly access control and password policies. A simple example of such groups are the users and the admins groups.
-In most of the cases these groups are auto defined in terms of access, rules of usage, conditions to be part of, etc.
-
-### Bamboo
-
-Atlassian's CI tool similar to GitLab CI and Jenkins.
-
-### Basic Subscription
-
-Entry level [subscription](https://about.gitlab.com/pricing/) for GitLab EE currently available in packs of 10.
-
-### Bitbucket
-
-Atlassian's web hosting service for Git and Mercurial Projects. Read about [migrating](../../user/project/import/bitbucket.md) from BitBucket to a GitLab instance.
-
-### Branch
-
-A branch is a parallel version of a repository. This allows you to work on the repository without affecting the "master" branch, and without affecting the current "live" version. When you have made all your changes to your branch you can then merge to the master. When your merge request is accepted your changes will be "live."
-
-### Branded Login
-
-Having your own logo on [your GitLab instance login page](../../customization/branded_login_page.md) instead of the GitLab logo.
-
-### Job triggers (Build Triggers)
-These protect your code base against breaks, for instance when a team is working on the same project. Learn about [setting up](../../ci/triggers/README.md) job triggers.
-
-### CEPH
-
- A distributed object store and file [system](http://ceph.com/) designed to provide excellent performance, reliability and scalability.
-
-### ChatOps
-
-The ability to [initiate an action](https://gitlab.com/gitlab-org/omnibus-gitlab/issues/1412) from chat. ChatBots run in your chat application and give you the ability to do "anything" from chat.
-
-### Clone
-
-A [copy](https://git-scm.com/docs/git-clone) of a repository stored on your machine that allows you to use your own editor without being online, but still tracks the changes made remotely.
-
-### Code Review
-
-Examination of a program's code. The main aim is to maintain high quality standards of code that is being shipped. Merge requests [serve as a code review tool](https://about.gitlab.com/2014/09/29/gitlab-flow/) in GitLab.
-
-### Code Snippet
-
-A small amount of code, usually selected for the purpose of showing other developers how to do something specific or reproduce a problem.
-
-### Collaborator
-
-Person with read and write access to a repository who has been invited by repository owner.
-
-### Commit
-
-A [change](https://git-scm.com/docs/git-commit) (revision) to a file that also creates an ID, allowing you to see revision history and the author of the changes.
-
-### Community
-
-[Everyone](https://about.gitlab.com/community/) who uses GitLab.
-
-### Confluence
-
-Atlassian's product for collaboration on documents and projects.
-
-### Continuous Delivery
-
-A [software engineering approach](https://about.gitlab.com/2016/08/05/continuous-integration-delivery-and-deployment-with-gitlab/) in which continuous integration, automated testing, and automated deployment capabilities allow software to be developed and deployed rapidly, reliably and repeatedly with minimal human intervention. Still, the deployment to production is defined strategically and triggered manually. [Amazon moves toward continuous delivery](https://www.youtube.com/watch?v=esEFaY0FDKc)
-
-### Continuous Deployment
-
-A [software development practice](https://about.gitlab.com/2016/08/05/continuous-integration-delivery-and-deployment-with-gitlab/) in which every code change goes through the entire pipeline and is put into production automatically, resulting in many production deployments every day. It does everything that Continuous Delivery does, but the process is fully automated, there's no human intervention at all. [The difference between Continuous Delivery and Continuous Integration.](https://www.youtube.com/watch?v=igwFj8PPSnw)
-
-### Continuous Integration
-
-A [software development practice](https://about.gitlab.com/2016/08/05/continuous-integration-delivery-and-deployment-with-gitlab/) in which you build and test software every time a developer pushes code to the application, and it happens several times a day. [Thoughtworks discusses continuous integration.](https://www.thoughtworks.com/continuous-integration)
-
-### Contributor
-
-Term used for a person contributing to an open source project.
-
-### Conversational Development (ConvDev)
-
-A [natural evolution](https://about.gitlab.com/2016/09/14/gitlab-live-event-recap/) of software development that carries a conversation across functional groups throughout the development process, enabling developers to track the full path of development in a cohesive and intuitive way. ConvDev accelerates the development lifecycle by fostering collaboration and knowledge sharing from idea to production.
-
-### Cycle Analytics
-
-See <https://gitlab.com/gitlab-org/gitlab-ce/issues/22458>
-
-### Cycle Time
-
-The time it takes to move from [idea to production](https://about.gitlab.com/2016/08/05/continuous-integration-delivery-and-deployment-with-gitlab/#from-idea-to-production-with-gitlab).
-
-### Data Centre
-
-Atlassian product for High Availability.
-
-### Dependencies
-
-As in "specify [dependencies](https://gitlab.com/gitlab-org/gitlab-ce/issues/14728) between stages."
-
-### Deploy Keys
-
-A [SSH key](../../gitlab-basics/create-your-ssh-keys.md)stored on your server that grants access to a single GitLab repository. This is used by a GitLab runner to clone a project's code so that tests can be run against the checked out code.
-
-### Developer
-
-For us at GitLab, this means a software developer, or someone who makes software. It is also one of the levels of access in our multi-level approval system.
-
-### DevOps
-
-The intersection of software engineering, quality assurance, and technology operations. Explore more DevOps topics in the [glossary by XebiaLabs](https://xebialabs.com/glossary/)
-
-### Diff
-
-The difference between two commits, or saved changes. This will also be shown visually after the changes.
-
-### Directory
-
-A folder used for storing multiple files.
-
-### Docker Container Registry
-
-A [feature](../../user/project/container_registry.md) of [GitLab projects](https://about.gitlab.com/2016/05/23/gitlab-container-registry/). Containers wrap up a piece of software in a complete filesystem that contains everything it needs to run: code, runtime, system tools, system libraries – anything you can install on a server. This guarantees that it will always run the same, regardless of the environment it is running in.
-
-### Dynamic Environment (review apps)
-
-### EC2 Instance
-
-### Elasticsearch
-
-Elasticsearch is a flexible, scalable and powerful search service. When [enabled](https://gitlab.com/help/integration/elasticsearch.md), it helps keep GitLab's search fast when dealing with a huge amount of data.
-
-### Emacs
-
-External reference: <https://www.masteringemacs.org/article/mastering-key-bindings-emacs>
-
-### First Byte
-
-External reference: <https://en.wikipedia.org/wiki/Time_To_First_Byte>
-
-First Byte (sometimes referred to as time to first byte or [TTFB](https://en.wikipedia.org/wiki/Time_To_First_Byte)) measures the time between making a request and receiving the first byte of information in return. As a result, First Byte encompasses everything that is the backend as well as network transit issues. It differs from [_Speed Index_](#speed-index) mostly by frontend related issues which are included in Speed Index such as javascript loading, page rendering, and so on.
-
-### Fork
-
-Your [own copy](../../workflow/forking_workflow.md) of a repository that allows you to make changes to the repository without affecting the original.
-
-### Funnel, or: TOFU, MOFU, BOFU
-
-External reference: [Blog post](https://www.weidert.com/whole_brain_marketing_blog/bid/113688/ToFu-MoFu-BoFu-Serving-Up-The-Right-Content-for-Lead-Nurturing)
-
-TOFU: top of funnel
-MOFU: middle of funnel
-BOFU: bottom of funnel
-
-### Gerrit
-
-A code review [tool](https://www.gerritcodereview.com/) built on top of Git.
-
-### Git Attributes
-
-A [git attributes file](https://git-scm.com/docs/gitattributes) is a simple text file that gives attributes to pathnames.
-
-### Git Hooks
-
-[Scripts](https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks) you can use to trigger actions at certain points.
-
-Difference between a [webhook](#webhooks) and a git hook: a git hook is local to its repo (usually) while a webhook is not (it can make API or http calls). So for example if you want your linter to fire before you commit, you can set that up with a git hook. If the linter fails, the commit does not go through. A git hook _can_ be configured to go beyond its repo, e.g. by having it make an API call.
-
-### GitHost.io
-
-A single-tenant solution that provides GitLab CE or EE as a managed service. GitLab Inc. is responsible for installing, updating, hosting, and backing up customers' own private and secure GitLab instance.
-
-### GitHub
-
-A web-based Git repository hosting service with an enterprise offering. Its main features are: issue tracking, pull request with code review, abundancy of integrations and wiki. It offers free public repos, private repos and enterprise services are paid. Read about [importing a project](../../workflow/importing/import_projects_from_github.md) from GitHub to GitLab.
-
-### GitLab CE
-
-Our free on Premise solution with >100,000 users
-
-### GitLab CI
-
-Our own Continuous Integration [feature](https://about.gitlab.com/gitlab-ci/) that is shipped with each instance
-
-### GitLab EE
-
-Our premium on premise [solution](https://about.gitlab.com/features/#enterprise) that currently has Basic, Standard and Plus subscription packages with additional features and support.
-
-### GitLab.com
-
-Our free SaaS for public and private repositories.
-
-### GitLab Geo
-
-Allows you to replicate your GitLab instance to other geographical locations as a read-only fully operational version. It [can be used](../../administration/geo/replication/index.md) for cloning and fetching projects, in addition to reading any data. This will make working with large repositories over large distances much faster.
-
-### GitLab High Availability
-
-### GitLab Master Plan
-
-Related blog post: <https://about.gitlab.com/2016/09/13/gitlab-master-plan/>.
-
-### GitLab Pages
-
-These allow you to [create websites](https://gitlab.com/help/pages/README.md) for your GitLab projects, groups, or user account.
-
-### GitLab Runner
-
-Related project: <https://gitlab.com/gitlab-org/gitlab-runner>
-
-### Gitolite
-
-An [access layer](https://git-scm.com/book/en/v1/Git-on-the-Server-Gitolite) that sits on top of Git. Users are granted access to repos via a simple config file. As an admin, you only need the users' public SSH key and a username.
-
-### Gitorious
-
-A web-based hosting service for projects using Git. It was acquired by GitLab and we discontinued the service. Read the[Gitorious Acquisition Blog Post](https://about.gitlab.com/2015/03/03/gitlab-acquires-gitorious/).
-
-### Go
-
-An open source programming [language](https://golang.org/).
-
-### Gogs
-
-External reference: <https://gogs.io/>
-
-### GUI/ Git GUI
-
-A portable [graphical interface](https://git-scm.com/docs/git-gui) to Git that allows users to make changes to their repository by making new commits, amending existing ones, creating branches, performing local merges, and fetching/pushing to remote repositories.
-
-### High Availability for Disaster Recovery (HADR)
-
-Sometimes written HA/DR, this usually refers to a strategy for having a failover server in place in case the main server fails.
-
-### Hip Chat
-
-Atlassian's real time chat application for teams, Hip Chat is a competitor to Slack, RocketChat and MatterMost.
-
-### High Availability
-
-Refers to a [system or component](https://about.gitlab.com/high-availability/) that is continuously operational for a desirably long length of time. Availability can be measured relative to "100% operational" or "never failing."
-
-### Inner-sourcing
-
-The [use of](https://about.gitlab.com/2014/09/05/innersourcing-using-the-open-source-workflow-to-improve-collaboration-within-an-organization/) open source development techniques within the corporation.
-
-### Internet Relay Chat (IRC)
-
-An [application layer protocol](http://www.irchelp.org/) that facilitates communication in the form of text.
-
-### Issue Tracker
-
-A [tool](../../integration/external-issue-tracker.md) used to manage, organize, and maintain a list of issues, making it easier for an organization to manage.
-
-### Jenkins
-
-An Open Source CI tool written using the Java programming language. [Jenkins](https://jenkins.io/) does the same job as GitLab CI, Bamboo, and Travis CI. It is extremely popular. Related [documentation](../../integration/jenkins.md).
-
-### Jira
-
-Atlassian's [project management software](https://www.atlassian.com/software/jira), i.e. a complex issue tracker. GitLab [can be configured](../../project_services/jira.md) to interact with JIRA Core either using an on-premise instance or the SaaS solution that Atlassian offers.
-
-### JUnit
-
-A testing framework for the Java programming language, [JUnit](http://junit.org/junit4/) has been important in the evolution of test-driven development.
-
-### Kerberos
-
-A network authentication [protocol](http://web.mit.edu/kerberos/) that uses secret-key cryptography for security.
-
-### Kubernetes
-
-An open source container cluster manager originally designed by Google. It's basically a platform for automating deployment, scaling, and operations of application containers over clusters of hosts.
-
-### Labels
-
-An [identifier](../../user/project/labels.md) to describe a group of one or more specific file revisions.
-
-### Lightweight Directory Access Protocol (LDAP)
-
- A directory (electronic address book) with user information (e.g. name, phone_number etc.)
-
-### LDAP User Authentication
-
-GitLab [integrates](../../administration/auth/ldap.md) with LDAP to support user authentication. This enables GitLab to sign in people from an LDAP server (i.e., allowing people whose names are on the electronic user directory server to be able to use their LDAP accounts to login.)
-
-### LDAP Group Sync
-
-Allows you to synchronize the members of a GitLab group with one or more LDAP groups.
-
-### Lint
-
-Static code analysis for our various file types. For example, we use [scss-lint](https://github.com/brigade/scss-lint) to ensure that a consistent code styling is respected. Similar tools: rubocop / eslint.
-
-### Load Balancer
-
-A [device](https://en.wikipedia.org/wiki/Load_balancing_(computing)) that distributes network or application traffic across multiple servers.
-
-### Git Large File Storage (LFS)
-
-A way [to enable](https://about.gitlab.com/2015/11/23/announcing-git-lfs-support-in-gitlab/) git to handle large binary files by using reference pointers within small text files to point to the large files. Large files such as high resolution images and videos, audio files, and assets can be called from a remote server.
-
-### Linux
-
-An operating system like Windows or OS X. It is mostly used by software developers and on servers.
-
-### Markdown
-
-A lightweight markup language with plain text formatting syntax designed so that it can be converted to HTML and many other formats using a tool by the same name. Markdown is often used to format readme files, for writing messages in online discussion forums, and to create rich text using a plain text editor. Checkout GitLab's [Markdown guide](https://gitlab.com/help/user/markdown.md).
-
-### Maria DB
-
-A community developed fork/variation of MySQL. MySQL is owned by Oracle.
-
-### Master
-
-Name of the [default branch](https://git-scm.com/book/en/v1/Git-Branching-What-a-Branch-Is) in every git repository.
-
-### Mattermost
-
-An open source, self-hosted messaging alternative to Slack. View GitLab's Mattermost [feature](https://gitlab.com/gitlab-org/gitlab-mattermost).
-
-### Mercurial
-
-A free distributed version control system similar to and a competitor with Git.
-
-### Merge
-
-Takes changes from one branch, and [applies them](https://git-scm.com/docs/git-merge) into another branch.
-
-### Merge Conflict
-
-[Arises](https://about.gitlab.com/2016/09/06/resolving-merge-conflicts-from-the-gitlab-ui/) when a merge can't be performed cleanly between two versions of the same file.
-
-#### Merge Request (MR)
-
-[Takes changes](../../gitlab-basics/add-merge-request.md) from one branch, and applies them into another branch.
-
-### Meteor
-
-A [platform](https://www.meteor.com) for building javascript apps.
-
-### Milestones
-
-Allow you to [organize issues](../../user/project/milestones/index.md) and merge requests in GitLab into a cohesive group, optionally setting a due date. A common use is keeping track of an upcoming software version. Milestones are created per-project.
-
-### Mirror Repositories
-
-A project that is set up to automatically have its branches, tags, and commits [updated from an upstream repository](../../workflow/repository_mirroring.md). This is useful when a repository you're interested in is located on a different server, and you want to be able to browse its content and activity using the familiar GitLab interface.
-
-### MIT License
-
-A type of software license. It lets people do anything with your code with proper attribution and without warranty. It is the most common license for open source applications written in Ruby on Rails. GitLab CE is issued under this [license](../../development/licensing.md). This means you can download the code, modify it as you want, and even build a new commercial product using the underlying code and it's not illegal. The only condition is that there is no form of warranty provided by GitLab so whatever happens when you use the code is your own problem.
-
-### Mondo Rescue
-
-A free disaster recovery [software](https://help.ubuntu.com/community/MondoMindi).
-
-#### Mount
-
-External reference:
-
-As stated on the [wikipedia page](https://en.wikipedia.org/wiki/Mount_(Unix)), "Mounting makes file systems, files, directories, devices and special files available for use and available to the user."
-
-For example, we have NFS servers where the _git files_ reside. In order for a worker node to "see" or "use" the git files, the NFS server needs to be _mounted_ on the worker; that is, the worker needs to know that the NFS server exists and how to connect to it. Think of it as getting a shared drive to show up in your Finder (on Mac) or Explorer (on Windows).
-
-### MySQL
-
-A relational [database](http://www.mysql.com/) owned by Oracle. Currently only supported if you are using EE.
-
-### Namespace
-
-A set of symbols that are used to organize objects of various kinds so that these objects may be referred to by name. Examples of namespaces in action include file systems that assign names to files; programming languages that organize their variables and subroutines in namespaces; and computer networks and distributed systems that assign names to resources, such as computers, printers, websites, (remote) files, etc.
-
-### Nginx
-
-A web [server](https://www.nginx.com/resources/wiki/) (pronounced "engine x"). [It can act](https://gitlab.com/gitlab-org/omnibus-gitlab/blob/master/doc/settings/nginx.md) as a reverse proxy server for HTTP, HTTPS, SMTP, POP3, and IMAP protocols, as well as a load balancer and an HTTP cache.
-
-### OAuth
-
-An open standard for authorization, commonly used as a way for internet users to log into third party websites using their Microsoft, Google, Facebook or Twitter accounts without exposing their password. GitLab [is](../../integration/oauth_provider.md) an OAuth2 authentication service provider.
-
-### Omnibus Packages
-
-A way to [package different services and tools](https://docs.gitlab.com/omnibus/) required to run GitLab, so that most developers can install it without laborious configuration.
-
-### On Premise
-
-On your own server. In GitLab, this [refers](https://about.gitlab.com/2015/02/12/why-ship-on-premises-in-the-saas-era/) to the ability to download GitLab EE/GitLab CE and host it on your own server rather than using GitLab.com, which is hosted by GitLab Inc's servers.
-
-### Open Core
-
-GitLab's [business model](https://about.gitlab.com/2016/07/20/gitlab-is-open-core-github-is-closed-source/). Coined by Andrew Lampitt in 2008, the [open core model](https://en.wikipedia.org/wiki/Open_core) primarily involves offering a "core" or feature-limited version of a software product as free and open-source software, while offering "commercial" versions or add-ons as proprietary software.
-
-### Open Source Software
-
-Software for which the original source code is freely [available](https://opensource.org/docs/osd) and may be redistributed and modified. GitLab prioritizes open source [stewardship](https://about.gitlab.com/2016/01/11/being-a-good-open-source-steward/). Including to providing access to the source code, open source software must comply with a number of criteria, among them free distribution and no discrimination against persons, groups, or fields of endeavor.
-
-#### Open Source Stewardship
-
-[Related blog post](https://about.gitlab.com/2016/01/11/being-a-good-open-source-steward/).
-
-### Owner
-
-The most powerful person on a GitLab project. They have the permissions of all the other users plus the additional permission of being able to destroy (i.e. delete) the project.
-
-### Platform as a Service (PaaS)
-
-Typically referred to in regards to application development, PaaS is a model in which a cloud provider delivers hardware and software tools to its users as a service.
-
-### Perforce
-
-The company that produces Helix. A commercial, proprietary, centralised VCS well known for its ability to version files of any size and type. They OEM a re-branded version of GitLab called "GitSwarm" that is tightly integrated with their "GitFusion" product, which in turn represents a portion of a Helix repository (called a depot) as a git repo.
-
-### Phabricator
-
-A suite of web-based software development collaboration tools, including the Differential code review tool, the Diffusion repository browser, the Herald change monitoring tool, the Maniphest bug tracker and the Phriction wiki. Phabricator integrates with Git, Mercurial, and Subversion.
-
-### Piwik Analytics
-
-An open source analytics software to help you analyze web traffic. It is similar to Google Analytics, except that the latter is not open source and information is stored by Google. In Piwik, the information is stored on your own server and hence is fully private.
-
-### Plus Subscription
-
-GitLab Premium EE [subscription](https://about.gitlab.com/pricing/) that includes training and dedicated Account Management and Service Engineer and complete support package.
-
-### PostgreSQL
-
-An [object-relational](https://en.wikipedia.org/wiki/PostgreSQL) database. Touted as the most advanced open source database, it is one of two database management systems [supported by](https://gitlab.com/gitlab-org/omnibus-gitlab/blob/master/doc/settings/database.md) GitLab, the other being MySQL.
-
-### Protected Branches
-
-A [feature](../../user/project/protected_branches.md) that protects branches from unauthorized pushes, force pushing or deletion.
-
-### Protected Tags
-
-A [feature](../../user/project/protected_tags.md) that protects tags from unauthorized creation, update or deletion
-
-### Pull
-
-Git command to [synchronize](https://git-scm.com/docs/git-pull) the local repository with the remote repository, by fetching all remote changes and merging them into the local repository.
-
-### Puppet
-
-A popular DevOps [automation tool](https://puppet.com/product/how-puppet-works).
-
-### Push
-
-Git [command](https://git-scm.com/docs/git-push) to send commits from the local repository to the remote repository. Read about [advanced push rules](https://gitlab.com/help/pages/README.md) in GitLab.
-
-### Raketasks
-
-### RE Read Only
-
-Permissions to see a file and its contents, but not change it.
-
-### Rebase
-
-In addition to the merge, the [rebase](https://git-scm.com/book/en/v2/Git-Branching-Rebasing) is a main way to integrate changes from one branch into another.
-
-### Regression
-
-A regression is something that used to work one way in the last release and then we made a **breaking change** and it no longer works the same way.
-
-_or_
-
-A regression is defined as a change that results in a negative impact on the functionality of an existing feature due to recent changes, i.e. the latest release.
-
-### Remote mirroring
-
-### (Git) Repository
-
-A directory where Git [has been initiatlized](https://git-scm.com/book/en/v2/Git-Basics-Getting-a-Git-Repository) to start version controlling your files. The history of your work is stored here. A remote repository is not on your machine, but usually online (like on GitLab.com, for instance). The main remote repository is usually called "Origin."
-
-##### Remote repository
-
-A [repository](https://about.gitlab.com/2015/05/18/simple-words-for-a-gitlab-newbie/) that is not-on-your-machine, so it's anything that is not your computer. Usually, it is online, GitLab.com for instance. The main remote repository is usually called “Origin”.
-
-### Requirements management
-
-Gives your distributed teams a single shared repository to collaborate and share requirements, understand their relationship to tests, and evaluate linked defects. It includes multiple, preconfigured requirement types.
-
-### Revision Control
-
-Also known as version control or source control, this is the management of changes to documents, computer programs, large web sites, and other collections of information. Changes are usually identified by a number or letter code, termed the "revision number," "revision level," or simply "revision."
-
-### RocketChat
-
-An open source chat application for teams, RocketChat is very similar to Slack but it is also open-source.
-
-### Route Table
-
-A route table contains rules (called routes) that determine where network traffic is directed. Each [subnet in a VPC](http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/VPC_Route_Tables.html) must be associated with a route table.
-
-### Runners
-
-Actual build machines/containers that [run and execute tests](https://gitlab.com/gitlab-org/gitlab-runner) you have specified to be run on GitLab CI.
-
-### Sidekiq
-
-The background job processor GitLab [uses](../../administration/troubleshooting/sidekiq.md) to asynchronously run tasks.
-
-### Software as a service (SaaS)
-
-Software that is hosted centrally and accessed on-demand (i.e. whenever you want to). This applies to GitLab.com.
-
-### Software Configuration Management (SCM)
-
-This term is often used by people when they mean "Version Control."
-
-### Scrum
-
-An Agile [framework](https://www.scrum.org/Resources/What-is-Scrum) designed to typically help complete complex software projects. It's made up of several parts: product requirements backlog, sprint planning, sprint (development), sprint review, and retrospec (analyzing the sprint). The goal is to end up with potentially shippable products.
-
-### Scrum Board
-
-The board used to track the status and progress of each of the sprint backlog items.
-
-### Shell
-
-Terminal on Mac OSX, GitBash on Windows, or Linux Terminal on Linux. You [use git](../../gitlab-basics/start-using-git.md) and make changes to GitLab projects in your shell. You [use git](../../gitlab-basics/start-using-git.md) and make changes to GitLab projects in your shell.
-
-### Shell command runner
-
-### Single-tenant
-
-The tenant purchases their own copy of the software and the software can be customized to meet the specific and needs of that customer. [GitHost.io](https://about.gitlab.com/handbook/positioning-faq/) is our provider of single-tenant 'managed cloud' GitLab instances.
-
-### Slack
-
-Real time messaging app for teams that is used internally by GitLab team members. GitLab users can enable [Slack integration](../../project_services/slack.md) to trigger push, issue, and merge request events among others.
-
-### Slash commands
-
-### Slave Servers
-
-Also known as secondary servers, these help to spread the load over multiple machines. They also provide backups when the master/primary server crashes.
-
-### Source Code
-
-Program code as typed by a computer programmer (i.e. it has not yet been compiled/translated by the computer to machine language).
-
-### Speed Index
-
-[Speed Index](https://sites.google.com/a/webpagetest.org/docs/using-webpagetest/metrics/speed-index) is "the average time at which visible parts of the page are displayed".
-
-### SSH Key
-
-A unique identifier of a computer. It is used to identify computers without the need for a password (e.g., On GitLab I have [added the ssh key](../../gitlab-basics/create-your-ssh-keys.md) of all my work machines so that the GitLab instance knows that it can accept code pushes and pulls from this trusted machines whose keys are I have added.)
-
-### Single Sign On (SSO)
-
-An authentication process that allows you enter one username and password to access multiple applications.
-
-### Staging Area
-
-[Staging occurs](https://git-scm.com/book/en/v2/Getting-Started-Git-Basics) before the commit process in git. The staging area is a file, generally contained in your Git directory, that stores information about what will go into your next commit. It’s sometimes referred to as the “index.""
-
-### Standard Subscription
-
-Our mid range EE subscription that includes 24/7 support and support for High Availability [Standard Subscription](https://about.gitlab.com/pricing/).
-
-### Stash
-
-Atlassian's Git on-premise solution. Think of it as Atlassian's GitLab EE, now known as BitBucket Server.
-
-### Static Site Generators (SSGs)
-
-A [software](https://wiki.python.org/moin/StaticSiteGenerator) that takes some text and templates as input and produces html files on the output.
-
-### Subversion
-
-Non-proprietary, centralized version control system.
-
-### Sudo
-
-A program that allows you to perform superuser/administrator actions on Unix Operating Systems (e.g., Linux, OS X.) It actually stands for 'superuser do.'
-
-### Subversion (SVN)
-
-An open source version control system. Read about [migrating from SVN](../../workflow/importing/migrating_from_svn.md) to GitLab using SubGit.
-
-### Tag
-
-[Represents](../../api/tags.md) a version of a particular branch at a moment in time.
-
-### Tenancy
-
-#### Multi-tenant
-
-A [multi-tenant](http://whatis.techtarget.com/definition/multi-tenancy) GitLab instance can have any number of customers - such as companies or groups of users using it. GitLab.com is an example of a multi-tenant GitLab instance.
-
-#### Single-tenant
-
-A [single-tenant](http://searchcloudapplications.techtarget.com/definition/single-tenancy) GitLab instance has only one customer - such as a company - using it. On premise GitLab instances are almost exclusively single-tenant.
-
-### Tool Stack
-
-The set of tools used in a process to achieve a common outcome (e.g. set of tools used in Application Lifecycle Management).
-
-### Trac
-
-An open source project management and bug tracking web [application](https://trac.edgewall.org/).
-
-### True-Up licensing model
-
-### Ubuntu
-
-### Untracked files
-
-New files that Git has not [been told](https://git-scm.com/book/en/v2/Git-Basics-Recording-Changes-to-the-Repository) to track previously. Add them by using the command "git add [file path]"
-
-### Upstream repository vs. GitLab repository
-
-[External conversation](https://news.ycombinator.com/item?id=12487112)
-
-### User
-
-Anyone interacting with the software.
-
-### Version Control Software (VCS)
-
-Version control is a system that records changes to a file or set of files over time so that you can recall specific versions later. VCS [has evolved](https://docs.google.com/presentation/d/16sX7hUrCZyOFbpvnrAFrg6tVO5_yT98IgdAqOmXwBho/edit#slide=id.gd69537a19_0_32) from local version control systems, to centralized version control systems, to the present [distributed version control systems](https://en.wikipedia.org/wiki/Distributed_version_control) like Git, Mercurial, Bazaar, and Darcs. If any server dies, and these systems were collaborating via it, any of the client repositories can be copied back up to the server to restore it.
-
-### Virtual Private Cloud (VPC)
-
-A [VPC](#virtual-private-cloud-vpc) is an on demand configurable pool of shared computing resources allocated within a public cloud environment, providing some isolation between the different users using the resources. GitLab users need to create a new Amazon VPC in order to [set up High Availability](../../install/aws/index.md).
-
-### Virtual private server (VPS)
-
-A [virtual machine](https://en.wikipedia.org/wiki/Virtual_private_server) sold as a service by an Internet hosting service. A VPS runs its own copy of an operating system, and customers have superuser-level access to that operating system instance, so they can install almost any software that runs on that OS.
-
-### VM Instance
-
-In object-oriented programming, an [instance](http://stackoverflow.com/questions/20461907/what-is-meaning-of-instance-in-programming) is a specific realization of any [object](https://cloud.google.com/compute/docs/instances/). An object may be varied in a number of ways. Each realized variation of that object is an instance. Therefore, a VM instance is an instance of a virtual machine, which is an emulation of a computer system.
-
-### Waterfall
-
-A [model](http://www.umsl.edu/~hugheyd/is6840/waterfall.html) of building software that involves collecting all requirements from the customer, then building and refining all the requirements and finally delivering the complete software to the customer that meets all the requirements they specified.
-
-### Webhooks
-
-A way for an app to [provide](../../user/project/integrations/webhooks.md) other applications with real-time information (e.g., send a message to a slack channel when a commit is pushed.) Read about setting up [custom git hooks](../../administration/custom_hooks.md) for when webhooks are insufficient.
-
-### Wiki
-
-A [website/system](http://www.wiki.com/) that allows for collaborative editing of its content by the users. In programming, wikis usually contain documentation of how to use the software.
-
-### Working area
-
-Files that have been modified but are not committed. Check them by using the command "git status".
-
-### Working Tree
-
-[Consists of files](http://stackoverflow.com/questions/3689838/difference-between-head-working-tree-index-in-git) that you are currently working on.
-
-### YAML
-
-A human-readable data serialization [language](http://www.yaml.org/about.html) that takes concepts from programming languages such as C, Perl, and Python, and ideas from XML and the data format of electronic mail.
+If you are looking for a definition of a specific term, please search these sites.
diff --git a/doc/university/high-availability/aws/README.md b/doc/university/high-availability/aws/README.md
index fa04e988042..caaa0a3675b 100644
--- a/doc/university/high-availability/aws/README.md
+++ b/doc/university/high-availability/aws/README.md
@@ -1,394 +1,5 @@
---
-comments: false
+redirect_to: '../../../install/aws/index.md'
---
-> **Note**: We **do not** recommend using the AWS Elastic File System (EFS), as it can result
-in [significantly degraded performance](../../../administration/high_availability/nfs.md#avoid-using-awss-elastic-file-system-efs).
-
-# High Availability on AWS
-
-GitLab on AWS can leverage many of the services that are already
-configurable with High Availability. These services have a lot of
-flexibility and are able to adapt to most companies, best of all is the
-ability to automate both vertical and horizontal scaling.
-
-In this article we'll go through a basic HA setup where we'll start by
-configuring our Virtual Private Cloud and subnets to later integrate
-services such as RDS for our database server and ElastiCache as a Redis
-cluster to finally manage them within an auto scaling group with custom
-scaling policies.
-
-***
-
-## Where to Start
-
-Login to your AWS account through the `My Account` dropdown on
-`https://aws.amazon.com` or through the URI assigned to your team such as
-`https://myteam.signin.aws.amazon.com/console/`. You'll start on the
-Amazon Web Services console from where we can choose all of the services
-we'll be using to configure our cloud infrastructure.
-
-### Reference Architecture
-
-![Reference Architecture](img/reference-arch2.png)
-
-***
-
-## Network
-
-We'll start by creating a VPC for our GitLab cloud infrastructure, then
-we can create subnets to have public and private instances in at least
-two AZs. Public subnets will require a Route Table keep an associated
-Internet Gateway.
-
-### VPC
-
-Start by looking for the VPC option on the web console. Now create a new
-VPC. We can use `10.0.0.0/16` for the CIDR block and leave tenancy as
-default if we don't require dedicated hardware.
-
-![New VPC](img/new_vpc.png)
-
-If you're setting up the Elastic File System service then select the VPC
-and from the Actions dropdown choose Edit DNS Hostnames and select Yes.
-
-### Subnet
-
-Now let's create some subnets in different Availability Zones. Make sure
-that each subnet is associated to the VPC we just created, that it has
-a distinct VPC and lastly that CIDR blocks don't overlap. This will also
-allow us to enable multi-AZ for redundancy.
-
-We will create private and public subnets to match load balancers and
-RDS instances as well.
-
-![Subnet Creation](img/subnet.png)
-
-The subnets are listed with their name, AZ and CIDR block:
-
-- gitlab-public-10.0.0.0 - us-west-2a - 10.0.0.0
-- gitlab-private-10.0.1.0 - us-west-2a - 10.0.1.0
-- gitlab-public-10.0.2.0 - us-west-2b - 10.0.2.0
-- gitlab-private-10.0.3.0 - us-west-2b - 10.0.3.0
-
-### Route Table
-
-Up to now all our subnets are private. We need to create a Route Table
-to associate an Internet Gateway. On the same VPC dashboard choose
-Route Tables on the left column and give it a name and associate it to
-our newly created VPC.
-
-![Route Table](img/route_table.png)
-
-### Internet Gateway
-
-Now still on the same dashboard head over to Internet Gateways and
-create a new one. After its created press on the `Attach to VPC` button and
-select our VPC.
-
-![Internet Gateway](img/ig.png)
-
-### Configure Subnets
-
-Go back to the Router Tables screen and select the newly created one,
-press the Routes tab on the bottom section and edit it. We need to add a
-new target which will be our Internet Gateway and have it receive
-traffic from any destination.
-
-![Subnet Config](img/ig-rt.png)
-
-Before leaving this screen select the next tab to the right which is
-Subnet Associations and add our public subnets. If you followed our
-naming convention they should be easy to find.
-
-***
-
-## Database with RDS
-
-For our database server we will use Amazon RDS which offers Multi-AZ
-for redundancy. Let's start by creating a subnet group and then we'll
-create the actual RDS instance.
-
-### Subnet Group
-
-From the RDS dashboard select Subnet Groups. Lets select our VPC from
-the VPC ID dropdown and at the bottom we can add our private subnets.
-
-![Subnet Group](img/db-subnet-group.png)
-
-### RDS
-
-Select the RDS service from the Database section and create a new
-PostgreSQL instance. After choosing between a Production or
-Development instance we'll start with the actual configuration. On the
-image below we have the settings for this article but note the
-following two options which are of particular interest for HA:
-
-1. Multi-AZ-Deployment is recommended as redundancy. Read more at
- [High Availability (Multi-AZ)](http://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Concepts.MultiAZ.html)
-1. While we chose a General Purpose (SSD) for this article a Provisioned
- IOPS (SSD) is best suited for HA. Read more about it at
- [Storage for Amazon RDS](http://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/CHAP_Storage.html)
-
-![RDS Instance Specs](img/instance_specs.png)
-
-The rest of the setting on this page request a DB identifier, username,
-and a master password. We've chosen to use `gitlab-ha`, `gitlab` and a
-very secure password respectively. Keep these in hand for later.
-
-![Network and Security](img/rds-net-opt.png)
-
-Make sure to choose our gitlab VPC, our subnet group, not have it public,
-and to leave it to create a new security group. The only additional
-change which will be helpful is the database name for which we can use
-`gitlabhq_production`.
-
-***
-
-## ElastiCache
-
-EC is an in-memory hosted caching solution. Redis maintains its own
-persistence and is used for certain types of application.
-
-Let's choose the ElastiCache service in the Database section from our
-AWS console. Now let's create a cache subnet group which will be very
-similar to the RDS subnet group. Make sure to select our VPC and its
-private subnets.
-
-![ElastiCache](img/ec-subnet.png)
-
-Now press the Launch a Cache Cluster and choose Redis for our
-DB engine. You'll be able to configure details such as replication,
-Multi-AZ and node types. The second section will allow us to choose our
-subnet and security group and
-
-![Redis Cluster details](img/redis-cluster-det.png)
-
-![Redis Network](img/redis-net.png)
-
-***
-
-## Network File System
-
-GitLab requires a shared filesystem such as NFS. The file share(s) will be
-mounted on all application servers. There are a variety of ways to build an
-NFS server on AWS.
-
-One option is to use a third-party AMI that offers NFS as a service. A [search
-for 'NFS' in the AWS Marketplace](https://aws.amazon.com/marketplace/search/results?x=0&y=0&searchTerms=NFS&page=1&ref_=nav_search_box)
-shows options such as NetApp, SoftNAS and others.
-
-Another option is to build a simple NFS server using a vanilla Linux server backed
-by AWS Elastic Block Storage (EBS).
-
-> **Note:** GitLab does not recommend using AWS Elastic File System (EFS). See
- details in [High Availability NFS documentation](../../../administration/high_availability/nfs.md#avoid-using-awss-elastic-file-system-efs)
-
-***
-
-## Initiate AMI
-
-We are going to launch an EC2 instance and bake an image so that we can
-later use it for auto scaling. We'll also take this opportunity to add an
-extension to our RDS through this temporary EC2 instance.
-
-### EC2 Instance
-
-Look for the EC2 option and choose to create an instance. We'll need at
-least a t2.medium type and for this article we'll choose an Ubuntu 14.04
-HVM 64-bit. In the Configure Instance section choose our GitLab VPC and
-a public subnet. I'd choose at least 10GB of storage.
-
-In the security group we'll create a new one considering that we need to
-SSH into the instance and also try it out through http. So let's add the
-http traffic from anywhere and name it something such as
-`gitlab-ec2-security-group`.
-
-While we wait for it to launch we can allocate an Elastic IP and
-associate it with our new EC2 instance.
-
-### RDS and Redis Security Group
-
-After the instance is being created we will navigate to our EC2 security
-groups and add a small change for our EC2 instances to be able to
-connect to RDS. First copy the security group name we just defined,
-namely `gitlab-ec2-security-group`, and edit select the RDS security
-group and edit the inbound rules. Choose the rule type to be PostgreSQL
-and paste the name under source.
-
-![RDS security group](img/rds-sec-group.png)
-
-Similar to the above we'll jump to the `gitlab-ec2-security-group` group
-and add a custom TCP rule for port 6379 accessible within itself.
-
-### Install GitLab
-
-To connect through SSH you will need to have the `pem` file which you
-chose available and with the correct permissions such as `400`.
-
-After accessing your server don't forget to update and upgrade your
-packages.
-
- sudo apt-get update && sudo apt-get upgrade -y
-
-Then follow installation instructions from
-[GitLab](https://about.gitlab.com/downloads-ee/#ubuntu1404), but before
-running reconfigure we need to make sure all our services are tied down
-so just leave the reconfigure command until after we edit our gitlab.rb
-file.
-
-### Extension for PostgreSQL
-
-Connect to your new RDS instance to verify access and to install
-a required extension. We can find the host or endpoint by selecting the
-instance and we just created and after the details drop down we'll find
-it labeled as 'Endpoint'; do remember not to include the colon and port
-number.
-
- sudo /opt/gitlab/embedded/bin/psql -U gitlab -h <rds-endpoint> -d gitlabhq_production
- psql (9.4.7)
- Type "help" for help.
-
- gitlab=# CREATE EXTENSION pg_trgm;
- gitlab=# \q
-
-### Configure GitLab
-
-While connected to your server edit the `gitlab.rb` file at `/etc/gitlab/gitlab.rb`
-find the `external_url 'http://gitlab.example.com'` option and change it
-to the domain you will be using or the public IP address of the current
-instance to test the configuration.
-
-For a more detailed description about configuring GitLab read [Configuring GitLab for HA](http://docs.gitlab.com/ee/administration/high_availability/gitlab.html)
-
-Now look for the GitLab database settings and uncomment as necessary. In
-our current case we'll specify the adapter, encoding, host, db name,
-username, and password.
-
- gitlab_rails['db_adapter'] = "postgresql"
- gitlab_rails['db_encoding'] = "unicode"
- gitlab_rails['db_database'] = "gitlabhq_production"
- gitlab_rails['db_username'] = "gitlab"
- gitlab_rails['db_password'] = "mypassword"
- gitlab_rails['db_host'] = "<rds-endpoint>"
-
-Next, we only need to configure the Redis section by adding the host and
-uncommenting the port.
-
-The last configuration step is to [change the default file locations ](http://docs.gitlab.com/ee/administration/high_availability/nfs.html)
-to make the EFS integration easier to manage.
-
- gitlab_rails['redis_host'] = "<redis-endpoint>"
- gitlab_rails['redis_port'] = 6379
-
-Finally, run reconfigure. You might find it useful to run a check and
-a service status to make sure everything has been set up correctly.
-
- sudo gitlab-ctl reconfigure
- sudo gitlab-rake gitlab:check
- sudo gitlab-ctl status
-
-If everything looks good copy the Elastic IP over to your browser and
-test the instance manually.
-
-### AMI
-
-After you finish testing your EC2 instance go back to its dashboard and
-while the instance is selected press on the Actions dropdown to choose
-Image -> Create an Image. Give it a name and description and confirm.
-
-***
-
-## Load Balancer
-
-On the same dashboard look for Load Balancer on the left column and press
-the Create button. Choose a classic Load Balancer, our gitlab VPC, not
-internal and make sure its listening for HTTP and HTTPS on port 80.
-
-Here is a tricky part though, when adding subnets we need to associate
-public subnets instead of the private ones where our instances will
-actually live.
-
-On the security group section let's create a new one named
-`gitlab-loadbalancer-sec-group` and allow both HTTP ad HTTPS traffic
-from anywhere.
-
-The Load Balancer Health will allow us to indicate where to ping and what
-makes up a healthy or unhealthy instance.
-
-We won't add the instance on the next session because we'll destroy it
-momentarily as we'll be using the image we were creating. We will keep
-the Enable Cross-Zone and Enable Connection Draining active.
-
-After we finish creating the Load Balancer we can revisit our Security
-Groups to improve access only through the ELB and any other requirement
-you might have.
-
-***
-
-## Auto Scaling Group
-
-Our AMI should be done by now so we can start working on our Auto
-Scaling Group.
-
-This option is also available through the EC2 dashboard on the left
-sidebar. Press on the create button. Select the new image on My AMIs and
-give it a `t2.medium` size. To be able to use Elastic File System we need
-to add a script to mount EFS automatically at launch. We'll do this at
-the Advanced Details section where we have a [User Data](http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/user-data.html)
-text area that allows us to add a lot of custom configurations which
-allows you to add a custom script for when launching an instance. Let's
-add the following script to the User Data section:
-
- #cloud-config
- package_upgrade: true
- packages:
- - nfs-common
- runcmd:
- - mkdir -p /gitlab-data
- - chown ec2-user:ec2-user /gitlab-data
- - echo "$(curl --silent http://169.254.169.254/latest/meta-data/placement/availability-zone).file-system-id.aws-region.amazonaws.com:/ /gitlab-data nfs defaults,vers=4.1 0 0" >> /etc/fstab
- - mount -a -t nfs
- - sudo gitlab-ctl reconfigure
-
-On the security group section we can choose our existing
-`gitlab-ec2-security-group` group which has already been tested.
-
-After this is launched we are able to start creating our Auto Scaling
-Group. Start by giving it a name and assigning it our VPC and private
-subnets. We also want to always start with two instances and if you
-scroll down to Advanced Details we can choose to receive traffic from ELBs.
-Let's enable that option and select our ELB. We also want to use the ELB's
-health check.
-
-![Auto scaling](img/auto-scaling-det.png)
-
-### Policies
-
-This is the really great part of Auto Scaling, we get to choose when AWS
-launches new instances and when it removes them. For this group we'll
-scale between 2 and 4 instances where one instance will be added if CPU
-utilization is greater than 60% and one instance is removed if it falls
-to less than 45%. Here are the complete policies:
-
-![Policies](img/policies.png)
-
-You'll notice that after we save this AWS starts launching our two
-instances in different AZs and without a public IP which is exactly what
-we where aiming for.
-
-***
-
-## Final Thoughts
-
-After you're done with the policies section have some fun trying to break
-instances. You should be able to see how the Auto Scaling Group and the
-EC2 screen starts bringing them up again.
-
-High Availability is a vast area, we went mostly through scaling and
-some redundancy options but it might also imply Geographic replication.
-There is a lot of ground yet to cover so have a read through these other
-resources and feel free to open an issue to request additional material.
-
-- [GitLab High Availability](../../../administration/high_availability/README.md)
-- [GitLab Geo](../../../administration/geo/replication/index.md)
+This document was moved to [another location](../../../install/aws/index.md).
diff --git a/doc/university/high-availability/aws/img/auto-scaling-det.png b/doc/university/high-availability/aws/img/auto-scaling-det.png
deleted file mode 100644
index cf32c024bf8..00000000000
--- a/doc/university/high-availability/aws/img/auto-scaling-det.png
+++ /dev/null
Binary files differ
diff --git a/doc/university/high-availability/aws/img/db-subnet-group.png b/doc/university/high-availability/aws/img/db-subnet-group.png
deleted file mode 100644
index 875184af310..00000000000
--- a/doc/university/high-availability/aws/img/db-subnet-group.png
+++ /dev/null
Binary files differ
diff --git a/doc/university/high-availability/aws/img/ec-subnet.png b/doc/university/high-availability/aws/img/ec-subnet.png
deleted file mode 100644
index 43ef76b62d3..00000000000
--- a/doc/university/high-availability/aws/img/ec-subnet.png
+++ /dev/null
Binary files differ
diff --git a/doc/university/high-availability/aws/img/ig-rt.png b/doc/university/high-availability/aws/img/ig-rt.png
deleted file mode 100644
index 62cca074a1e..00000000000
--- a/doc/university/high-availability/aws/img/ig-rt.png
+++ /dev/null
Binary files differ
diff --git a/doc/university/high-availability/aws/img/ig.png b/doc/university/high-availability/aws/img/ig.png
deleted file mode 100644
index 2798d4beac3..00000000000
--- a/doc/university/high-availability/aws/img/ig.png
+++ /dev/null
Binary files differ
diff --git a/doc/university/high-availability/aws/img/instance_specs.png b/doc/university/high-availability/aws/img/instance_specs.png
deleted file mode 100644
index 2a2b80103fb..00000000000
--- a/doc/university/high-availability/aws/img/instance_specs.png
+++ /dev/null
Binary files differ
diff --git a/doc/university/high-availability/aws/img/new_vpc.png b/doc/university/high-availability/aws/img/new_vpc.png
deleted file mode 100644
index d872554fab7..00000000000
--- a/doc/university/high-availability/aws/img/new_vpc.png
+++ /dev/null
Binary files differ
diff --git a/doc/university/high-availability/aws/img/policies.png b/doc/university/high-availability/aws/img/policies.png
deleted file mode 100644
index e99497a52a2..00000000000
--- a/doc/university/high-availability/aws/img/policies.png
+++ /dev/null
Binary files differ
diff --git a/doc/university/high-availability/aws/img/rds-net-opt.png b/doc/university/high-availability/aws/img/rds-net-opt.png
deleted file mode 100644
index 13130ac96b8..00000000000
--- a/doc/university/high-availability/aws/img/rds-net-opt.png
+++ /dev/null
Binary files differ
diff --git a/doc/university/high-availability/aws/img/rds-sec-group.png b/doc/university/high-availability/aws/img/rds-sec-group.png
deleted file mode 100644
index a88caba62c2..00000000000
--- a/doc/university/high-availability/aws/img/rds-sec-group.png
+++ /dev/null
Binary files differ
diff --git a/doc/university/high-availability/aws/img/redis-cluster-det.png b/doc/university/high-availability/aws/img/redis-cluster-det.png
deleted file mode 100644
index 51d3a08eab6..00000000000
--- a/doc/university/high-availability/aws/img/redis-cluster-det.png
+++ /dev/null
Binary files differ
diff --git a/doc/university/high-availability/aws/img/redis-net.png b/doc/university/high-availability/aws/img/redis-net.png
deleted file mode 100644
index 9022a9ada78..00000000000
--- a/doc/university/high-availability/aws/img/redis-net.png
+++ /dev/null
Binary files differ
diff --git a/doc/university/high-availability/aws/img/reference-arch2.png b/doc/university/high-availability/aws/img/reference-arch2.png
deleted file mode 100644
index 0f8790d0f74..00000000000
--- a/doc/university/high-availability/aws/img/reference-arch2.png
+++ /dev/null
Binary files differ
diff --git a/doc/university/high-availability/aws/img/route_table.png b/doc/university/high-availability/aws/img/route_table.png
deleted file mode 100644
index c8bef75f01a..00000000000
--- a/doc/university/high-availability/aws/img/route_table.png
+++ /dev/null
Binary files differ
diff --git a/doc/university/high-availability/aws/img/subnet.png b/doc/university/high-availability/aws/img/subnet.png
deleted file mode 100644
index 681c29bf07a..00000000000
--- a/doc/university/high-availability/aws/img/subnet.png
+++ /dev/null
Binary files differ
diff --git a/doc/university/support/README.md b/doc/university/support/README.md
index c8ade54a77c..9563492c137 100644
--- a/doc/university/support/README.md
+++ b/doc/university/support/README.md
@@ -1,12 +1,13 @@
---
comments: false
+type: reference
---
# Support Boot Camp
**Goal:** Prepare new Service Engineers at GitLab
-For each stage there are learning goals and content to support the learning of the engineer.
+For each stage, there are learning goals and content to support the learning of the engineer.
The goal of this boot camp is to have every Service Engineer prepared to help our customers
with whatever needs they might have and to also assist our awesome community with their
questions.
@@ -15,7 +16,7 @@ Always start with the [University Overview](../README.md) and then work
your way here for more advanced and specific training. Once you feel comfortable
with the topics of the current stage, move to the next.
-### Stage 1
+## Stage 1
Follow the topics on the [University Overview](../README.md), concentrate on it
during your first Stage, but also:
@@ -23,22 +24,22 @@ during your first Stage, but also:
- Perform the [first steps](https://about.gitlab.com/handbook/support/onboarding/#first-steps) of
the on-boarding process for new Service Engineers
-#### Goals
+### Goals
Aim to have a good overview of the Product and main features, Git and the Company
-### Stage 2
+## Stage 2
Continue to look over remaining portions of the [University Overview](../README.md) and continue on to these topics:
-#### Set up your development machine
+### Set up your development machine
Get your development machine ready to familiarize yourself with the codebase, the components, and to be prepared to reproduce issues that our users encounter
- Install the [GDK](https://gitlab.com/gitlab-org/gitlab-development-kit)
- [Set up OpenLDAP as part of this](https://gitlab.com/gitlab-org/gitlab-development-kit#openldap)
-#### Become comfortable with the Installation processes that we support
+### Become comfortable with the Installation processes that we support
It's important to understand how to install GitLab in the same way that our users do. Try installing different versions and upgrading and downgrading between them. Installation from source will give you a greater understanding of the components that we employ and how everything fits together.
@@ -54,13 +55,13 @@ Sometimes we need to upgrade customers from old versions of GitLab to latest, so
- Keep this up-to-date as patch and version releases become available, just like our customers would
- Try out the following installation path
- [Install GitLab 4.2 from source](https://gitlab.com/gitlab-org/gitlab-ce/blob/d67117b5a185cfb15a1d7e749588ff981ffbf779/doc/install/installation.md)
- - External MySQL database
- - External NGINX
+ - External MySQL database
+ - External NGINX
- Create some test data
- - Populated Repos
- - Users
- - Groups
- - Projects
+ - Populated Repos
+ - Users
+ - Groups
+ - Projects
- [Backup using our Backup rake task](../../raketasks/backup_restore.md#creating-a-backup-of-the-gitlab-system)
- [Upgrade to 5.0 source using our Upgrade documentation](https://gitlab.com/gitlab-org/gitlab-ee/blob/master/doc/update/4.2-to-5.0.md)
- [Upgrade to 5.1 source](https://gitlab.com/gitlab-org/gitlab-ee/blob/master/doc/update/5.0-to-5.1.md)
@@ -70,10 +71,10 @@ Sometimes we need to upgrade customers from old versions of GitLab to latest, so
- [Upgrade to Omnibus 7.14](https://docs.gitlab.com/omnibus/update/README.html#upgrading-from-a-non-omnibus-installation-to-an-omnibus-installation)
- [Restore backup using our Restore rake task](../../raketasks/backup_restore.md#restore)
- [Upgrade to latest EE](https://about.gitlab.com/downloads-ee)
- - (GitLab inc. only) Acquire and apply a license for the Enterprise Edition product, ask in #support
+ - (GitLab inc. only) Acquire and apply a license for the Enterprise Edition product, ask in #support
- Perform a downgrade from [EE to CE](../../downgrade_ee_to_ce/README.md)
-#### Start to learn about some of the integrations that we support
+### Start to learn about some of the integrations that we support
Our integrations add great value to GitLab. User questions often relate to integrating GitLab with existing external services and the configuration involved
@@ -83,28 +84,28 @@ Our integrations add great value to GitLab. User questions often relate to integ
- [Jenkins](../../integration/jenkins.md)
- [SAML](../../integration/saml.md)
-#### Goals
+### Goals
- Aim to be comfortable with installation of the GitLab product and configuration of some of the major integrations
- Aim to have an installation available for reproducing customer reports
-### Stage 3
+## Stage 3
-#### Understand the gathering of diagnostics for GitLab instances
+### Understand the gathering of diagnostics for GitLab instances
-- Learn about the GitLab checks that are available
+- Learn about the GitLab checks that are available:
- [Environment Information and maintenance checks](../../raketasks/maintenance.md)
- [GitLab check](../../raketasks/check.md)
- Omnibus commands
- - [Status](https://gitlab.com/gitlab-org/omnibus-gitlab/blob/master/doc/maintenance/README.md#get-service-status)
- - [Starting and stopping services](https://gitlab.com/gitlab-org/omnibus-gitlab/blob/master/doc/maintenance/README.md#starting-and-stopping)
- - [Starting a rails console](https://gitlab.com/gitlab-org/omnibus-gitlab/blob/master/doc/maintenance/README.md#invoking-rake-tasks)
+ - [Status](https://gitlab.com/gitlab-org/omnibus-gitlab/blob/master/doc/maintenance/README.md#get-service-status)
+ - [Starting and stopping services](https://gitlab.com/gitlab-org/omnibus-gitlab/blob/master/doc/maintenance/README.md#starting-and-stopping)
+ - [Starting a rails console](https://gitlab.com/gitlab-org/omnibus-gitlab/blob/master/doc/maintenance/README.md#invoking-rake-tasks)
-#### Learn about the Support process
+### Learn about the Support process
Zendesk is our Support Centre and our main communication line with our Customers. We communicate with customers through several other channels too
-- Familiarize yourself with ZenDesk
+- Familiarize yourself with ZenDesk:
- [UI Overview](https://support.zendesk.com/hc/en-us/articles/203661806-Introduction-to-the-Zendesk-agent-interface)
- [Updating Tickets](https://support.zendesk.com/hc/en-us/articles/212530318-Updating-and-solving-tickets)
- [Working w/ Tickets](https://support.zendesk.com/hc/en-us/articles/203690856-Working-with-tickets) *Read: avoiding agent collision.*
@@ -116,16 +117,16 @@ Zendesk is our Support Centre and our main communication line with our Customers
- Here you will find a large variety of queries mainly from our Users who are self hosting GitLab CE
- Understand the questions that are asked and dig in to try to find a solution
- [Proceed on to the GitLab.com Support Forum](https://about.gitlab.com/handbook/support/#gitlabcom-support-trackera-namesupp-foruma)
- - Here you will find queries regarding our own GitLab.com
- - Helping Users here will give you an understanding of our Admin interface and other tools
+ - Here you will find queries regarding our own GitLab.com
+ - Helping Users here will give you an understanding of our Admin interface and other tools
- [Proceed on to the Twitter tickets in Zendesk](https://about.gitlab.com/handbook/support/#twitter)
- - Here you will gain a great insight into our userbase
- - Learn from any complaints and problems and feed them back to the team
- - Tweets can range from help needed with GitLab installations, the API and just general queries
+ - Here you will gain a great insight into our userbase
+ - Learn from any complaints and problems and feed them back to the team
+ - Tweets can range from help needed with GitLab installations, the API and just general queries
- [Proceed on to Regular email Support tickets](https://about.gitlab.com/handbook/support/#regular-zendesk-tickets-a-nameregulara)
- - Here you will find tickets from our GitLab EE Customers and GitLab CE Users
- - Tickets here are extremely varied and often very technical
- - You should be prepared for these tickets, given the knowledge gained from previous tiers and your training
+ - Here you will find tickets from our GitLab EE Customers and GitLab CE Users
+ - Tickets here are extremely varied and often very technical
+ - You should be prepared for these tickets, given the knowledge gained from previous tiers and your training
- Check out your colleagues' responses
- Hop on to the #support-live-feed channel in Slack and see the tickets as they come in and are updated
- Read through old tickets that your colleagues have worked on
@@ -133,14 +134,14 @@ Zendesk is our Support Centre and our main communication line with our Customers
- [Learn about Cisco WebEx](https://about.gitlab.com/handbook/support/onboarding/#webexa-namewebexa)
- Training calls
- Information gathering calls
- - It's good to find out how new and prospective customers are going to be using the product and how they will set up their infrastructure
+ - It's good to find out how new and prospective customers are going to be using the product and how they will set up their infrastructure
- Diagnosis calls
- - When email isn't enough we may need to hop on a call and do some debugging along side the customer
- - These paired calls are a great learning experience
+ - When email isn't enough we may need to hop on a call and do some debugging along side the customer
+ - These paired calls are a great learning experience
- Upgrade calls
- Emergency calls
-#### Learn about the Escalation process for tickets
+### Learn about the Escalation process for tickets
Some tickets need specific knowledge or a deep understanding of a particular component and will need to be escalated to a Senior Service Engineer or Developer
@@ -148,7 +149,7 @@ Some tickets need specific knowledge or a deep understanding of a particular com
- Find the macros in Zendesk for ticket escalations
- Take a look at the [GitLab.com Team page](https://about.gitlab.com/team/) to find the resident experts in their fields
-#### Learn about raising issues and fielding feature proposals
+### Learn about raising issues and fielding feature proposals
- Understand what's in the pipeline and proposed features at GitLab: [Direction Page](https://about.gitlab.com/direction/)
- Practice searching issues and filtering using [labels](https://gitlab.com/gitlab-org/gitlab-ce/labels) to find existing feature proposals and bugs
@@ -157,15 +158,15 @@ Some tickets need specific knowledge or a deep understanding of a particular com
- Take a look at the [existing issue templates](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/CONTRIBUTING.md#issue-tracker) to see what is expected
- Raise issues for bugs in a manner that would make the issue easily reproducible. A Developer or a contributor may work on your issue
-#### Goals
+### Goals
- Aim to have a good understanding of the problems that customers are facing
- Aim to have gained experience in scheduling and participating in calls with customers
- Aim to have a good understanding of ticket flow through Zendesk and how to interact with our various channels
-### Stage 4
+## Stage 4
-#### Advanced GitLab topics
+### Advanced GitLab topics
Move on to understanding some of GitLab's more advanced features. You can make use of GitLab.com to understand the features from an end-user perspective and then use your own instance to understand setup and configuration of the feature from an Administrative perspective
@@ -179,11 +180,23 @@ Move on to understanding some of GitLab's more advanced features. You can make u
and the [CE codebase](https://gitlab.com/gitlab-org/gitlab-ce)
- Ask as many questions as you can think of on the `#support` chat channel
-#### Get initiated for on-call duty
+### Get initiated for on-call duty
- Read over the [public run-books to understand common tasks](https://gitlab.com/gitlab-com/runbooks)
- Create an issue on the internal Organization tracker to schedule time with the DevOps / Production team, so that you learn how to handle GitLab.com going down. Once you are trained for this, you are ready to be added to the on-call rotation.
-#### Goals
+### Goals
- Aim to become a fully-fledged Service Engineer!
+
+<!-- ## Troubleshooting
+
+Include any troubleshooting steps that you can foresee. If you know beforehand what issues
+one might have when setting this up, or when something is changed, or on upgrading, it's
+important to describe those, too. Think of things that may go wrong and include them here.
+This is important to minimize requests for support, and to avoid doc comments with
+questions that you know someone might ask.
+
+Each scenario can be a third-level heading, e.g. `### Getting error message X`.
+If you have none to add when creating a doc, leave this section in place
+but commented out to help encourage others to add to it in the future. -->
diff --git a/doc/university/training/gitlab_flow.md b/doc/university/training/gitlab_flow.md
index d7bc7bda43f..0ce92be4994 100644
--- a/doc/university/training/gitlab_flow.md
+++ b/doc/university/training/gitlab_flow.md
@@ -1,5 +1,6 @@
---
comments: false
+type: reference
---
# What is the GitLab Flow
@@ -41,5 +42,17 @@ comments: false
## More details
-For more information read through the [GitLab Flow](../../workflow/gitlab_flow.md)
+For more information, read through the [GitLab Flow](../../workflow/gitlab_flow.md)
documentation.
+
+<!-- ## Troubleshooting
+
+Include any troubleshooting steps that you can foresee. If you know beforehand what issues
+one might have when setting this up, or when something is changed, or on upgrading, it's
+important to describe those, too. Think of things that may go wrong and include them here.
+This is important to minimize requests for support, and to avoid doc comments with
+questions that you know someone might ask.
+
+Each scenario can be a third-level heading, e.g. `### Getting error message X`.
+If you have none to add when creating a doc, leave this section in place
+but commented out to help encourage others to add to it in the future. -->
diff --git a/doc/university/training/index.md b/doc/university/training/index.md
index 14f096b130f..ddfc662123d 100644
--- a/doc/university/training/index.md
+++ b/doc/university/training/index.md
@@ -1,5 +1,6 @@
---
comments: false
+type: index
---
# GitLab Training Material
@@ -8,3 +9,34 @@ All GitLab training material is stored in markdown format. Slides are
generated using [Deskset](http://www.decksetapp.com/).
All training material is open to public contribution.
+
+This section contains the following topics:
+
+- [Agile and Git](topics/agile_git.md).
+- [Bisect](topics/bisect.md).
+- [Cherry pick](topics/cherry_picking.md).
+- [Code review and collaboration with Merge Requests](topics/merge_requests.md).
+- [Configure your environment](topics/env_setup.md).
+- [Explore GitLab](topics/explore_gitlab.md).
+- [Feature branching](topics/feature_branching.md).
+- [Getting started](topics/getting_started.md).
+- [GitLab flow](gitlab_flow.md).
+- [GitLab Git workshop](user_training.md).
+- [Git add](topics/git_add.md).
+- [Git introduction](topics/git_intro.md).
+- [Git log](topics/git_log.md).
+- [Git stash](topics/stash.md).
+- [Merge conflicts](topics/merge_conflicts.md).
+- [Rollback commits](topics/rollback_commits.md).
+- [Subtree](topics/subtree.md).
+- [Tags](topics/tags.md).
+- [Unstage](topics/unstage.md).
+
+## Additional Resources
+
+1. [GitLab Documentation](http://docs.gitlab.com)
+1. [GUI Clients](http://git-scm.com/downloads/guis)
+1. [Pro Git book](http://git-scm.com/book)
+1. [Platzi Course](https://courses.platzi.com/courses/git-gitlab/)
+1. [Code School tutorial](http://try.github.io/)
+1. Contact us at `subscribers@gitlab.com`
diff --git a/doc/university/training/topics/additional_resources.md b/doc/university/training/topics/additional_resources.md
deleted file mode 100644
index 4871372d105..00000000000
--- a/doc/university/training/topics/additional_resources.md
+++ /dev/null
@@ -1,12 +0,0 @@
----
-comments: false
----
-
-# Additional Resources
-
-1. GitLab Documentation: <http://docs.gitlab.com>.
-1. GUI Clients: <http://git-scm.com/downloads/guis>.
-1. Pro Git book: <http://git-scm.com/book>.
-1. Platzi Course: <https://courses.platzi.com/courses/git-gitlab/>.
-1. Code School tutorial: <http://try.github.io/>.
-1. Contact us at `subscribers@gitlab.com`.
diff --git a/doc/university/training/topics/agile_git.md b/doc/university/training/topics/agile_git.md
index 251af99bed7..42d91a50045 100644
--- a/doc/university/training/topics/agile_git.md
+++ b/doc/university/training/topics/agile_git.md
@@ -4,22 +4,16 @@ comments: false
# Agile and Git
-----------
-
## Agile
Lean software development methods focused on collaboration and interaction
with fast and smaller deployment cycles.
-----------
-
## Where Git comes in
Git is an excellent tool for an Agile team considering that it allows
decentralized and simultaneous development.
-----------
-
### Branching And Workflows
Branching in an Agile environment usually happens around user stories with one
@@ -30,8 +24,7 @@ with his/her initials, and US id.
After its tested merge into master and remove the branch.
-----------
-
## What about GitLab
+
Tools like GitLab enhance collaboration by adding dialog around code mainly
through issues and merge requests.
diff --git a/doc/university/training/topics/bisect.md b/doc/university/training/topics/bisect.md
index 4848d0412c1..4178afa2086 100644
--- a/doc/university/training/topics/bisect.md
+++ b/doc/university/training/topics/bisect.md
@@ -4,16 +4,12 @@ comments: false
# Bisect
-----------
-
## Bisect
- Find a commit that introduced a bug
- Works through a process of elimination
- Specify a known good and bad revision to begin
-----------
-
## Bisect
1. Start the bisect process
@@ -23,11 +19,9 @@ comments: false
1. Tell bisect the result
1. Repeat the previous 2 items until you find the offending commit
-----------
-
## Setup
-```
+```sh
mkdir bisect-ex
cd bisect-ex
touch index.html
@@ -44,9 +38,7 @@ comments: false
vi index.html
```
-----------
-
-```
+```sh
# Add all good 3
git add -A
git commit -m "fourth commit"
@@ -64,11 +56,9 @@ comments: false
git commit -m "seventh commit"
```
-----------
-
## Commands
-```
+```sh
git bisect start
# Test your code
git bisect bad
diff --git a/doc/university/training/topics/cherry_picking.md b/doc/university/training/topics/cherry_picking.md
index df23024b6ee..fa0cb5fe6a4 100644
--- a/doc/university/training/topics/cherry_picking.md
+++ b/doc/university/training/topics/cherry_picking.md
@@ -4,16 +4,12 @@ comments: false
# Cherry Pick
-----------
-
## Cherry Pick
- Given an existing commit on one branch, apply the change to another branch
- Useful for backporting bug fixes to previous release branches
- Make the commit on the master branch and pick in to stable
-----------
-
## Cherry Pick
1. Check out a new 'stable' branch from 'master'
@@ -23,8 +19,6 @@ comments: false
1. Check out the 'stable' branch
1. Cherry pick the commit using the SHA obtained earlier
-----------
-
## Commands
```bash
diff --git a/doc/university/training/topics/env_setup.md b/doc/university/training/topics/env_setup.md
index 78ca30e0f55..305f5ecb1fb 100644
--- a/doc/university/training/topics/env_setup.md
+++ b/doc/university/training/topics/env_setup.md
@@ -4,7 +4,6 @@ comments: false
# Configure your environment
-----------
## Install
- **Windows**
@@ -22,8 +21,6 @@ comments: false
sudo apt-get install git-all
```
-----------
-
## Configure Git
One-time configuration of the Git client
@@ -33,8 +30,6 @@ git config --global user.name "Your Name"
git config --global user.email you@example.com
```
-----------
-
## Configure SSH Key
```bash
diff --git a/doc/university/training/topics/explore_gitlab.md b/doc/university/training/topics/explore_gitlab.md
index 84a1879cd92..4ca931d0e26 100644
--- a/doc/university/training/topics/explore_gitlab.md
+++ b/doc/university/training/topics/explore_gitlab.md
@@ -4,8 +4,6 @@ comments: false
# Explore GitLab projects
-----------
-
- Dashboard
- User Preferences
- Issues
diff --git a/doc/university/training/topics/feature_branching.md b/doc/university/training/topics/feature_branching.md
index 0df5f26dbea..d2efe634533 100644
--- a/doc/university/training/topics/feature_branching.md
+++ b/doc/university/training/topics/feature_branching.md
@@ -4,8 +4,6 @@ comments: false
# Feature branching
-----------
-
- Efficient parallel workflow for teams
- Develop each feature in a branch
- Keeps changes isolated
@@ -13,8 +11,6 @@ comments: false
- Push branches to the server frequently
- Hint: This is a cheap backup for your work-in-progress code
-----------
-
## Feature branching
1. Create a new feature branch called 'squash_some_bugs'
@@ -22,11 +18,9 @@ comments: false
1. Commit
1. Push
-----------
-
## Commands
-```
+```sh
git checkout -b squash_some_bugs
# Edit `bugs.rb`
git status
diff --git a/doc/university/training/topics/getting_started.md b/doc/university/training/topics/getting_started.md
index d76ff57bfa3..08027c5d15b 100644
--- a/doc/university/training/topics/getting_started.md
+++ b/doc/university/training/topics/getting_started.md
@@ -4,8 +4,6 @@ comments: false
# Getting Started
-----------
-
## Instantiating Repositories
- Create a new repository by instantiating it through:
@@ -19,8 +17,6 @@ comments: false
git clone <url>
```
-----------
-
## Central Repos
- To instantiate a central repository a `--bare` flag is required.
@@ -31,27 +27,22 @@ comments: false
git init --bare project-name.git
```
-----------
-
## Instantiate workflow with clone
1. Create a project in your user namespace.
- - Choose to import from 'Any Repo by URL' and use <https://gitlab.com/gitlab-org/training-examples.git>.
+ - Choose to import from 'Any Repo by URL' and use <https://gitlab.com/gitlab-org/training-examples.git>.
1. Create a '`Workspace`' directory in your home directory.
1. Clone the '`training-examples`' project.
-----------
-
## Commands
-```
+```sh
mkdir ~/workspace
cd ~/workspace
git clone git@gitlab.example.com:<username>/training-examples.git
cd training-examples
```
-----------
## Git concepts
@@ -67,8 +58,6 @@ Files that have been modified but are not committed.
Modified files that have been marked to go in the next commit.
-----------
-
## Committing Workflow
1. Edit '`edit_this_file.rb`' in '`training-examples`'
@@ -79,11 +68,9 @@ Modified files that have been marked to go in the next commit.
1. Push the commit to the remote
1. View the git log
-----------
-
## Commands
-```
+```sh
# Edit `edit_this_file.rb`
git status
git diff
@@ -93,8 +80,6 @@ git push origin master
git log
```
-----------
-
## Note
- git fetch vs pull
diff --git a/doc/university/training/topics/git_add.md b/doc/university/training/topics/git_add.md
index e02a7deab91..4c61d5eb175 100644
--- a/doc/university/training/topics/git_add.md
+++ b/doc/university/training/topics/git_add.md
@@ -4,8 +4,6 @@ comments: false
# Git Add
-----------
-
## Git Add
Adds content to the index or staging area.
@@ -22,8 +20,6 @@ Adds content to the index or staging area.
git add -A
```
-----------
-
## Git add continued
- Add all text files in current dir:
diff --git a/doc/university/training/topics/git_intro.md b/doc/university/training/topics/git_intro.md
index 127323c292c..845bb7f0a81 100644
--- a/doc/university/training/topics/git_intro.md
+++ b/doc/university/training/topics/git_intro.md
@@ -4,8 +4,6 @@ comments: false
# Git introduction
-----------
-
## Intro
<https://git-scm.com/about>
@@ -17,8 +15,6 @@ comments: false
- Adapts to nearly any workflow
- Fast, reliable and stable file format
-----------
-
## Help!
Use the tools at your disposal when you get stuck.
diff --git a/doc/university/training/topics/git_log.md b/doc/university/training/topics/git_log.md
index 763ef802a04..11addcd3ee1 100644
--- a/doc/university/training/topics/git_log.md
+++ b/doc/university/training/topics/git_log.md
@@ -4,44 +4,38 @@ comments: false
# Git Log
-----------
-
Git log lists commit history. It allows searching and filtering.
- Initiate log:
- ```
+ ```sh
git log
```
- Retrieve set number of records:
- ```
+ ```sh
git log -n 2
```
- Search commits by author. Allows user name or a regular expression.
- ```
+ ```sh
git log --author="user_name"
```
-----------
-
- Search by comment message:
- ```
+ ```sh
git log --grep="<pattern>"
```
- Search by date:
- ```
+ ```sh
git log --since=1.month.ago --until=3.weeks.ago
```
-----------
-
## Git Log Workflow
1. Change to workspace directory
@@ -51,11 +45,9 @@ Git log lists commit history. It allows searching and filtering.
1. Search by date
1. Combine
-----------
-
## Commands
-```
+```sh
cd ~/workspace
git clone git@gitlab.com:gitlab-org/gitlab-runner.git
cd gitlab-runner
diff --git a/doc/university/training/topics/merge_conflicts.md b/doc/university/training/topics/merge_conflicts.md
index a7d42904229..dd235fe3a81 100644
--- a/doc/university/training/topics/merge_conflicts.md
+++ b/doc/university/training/topics/merge_conflicts.md
@@ -4,15 +4,11 @@ comments: false
# Merge conflicts
-----------
-
- Happen often
- Learning to fix conflicts is hard
- Practice makes perfect
- Force push after fixing conflicts. Be careful!
-----------
-
## Merge conflicts
1. Checkout a new branch and edit `conflicts.rb`. Add 'Line4' and 'Line5'.
@@ -26,11 +22,9 @@ comments: false
1. Force push the changes.
1. Finally continue with the Merge Request.
-----------
-
## Commands
-```
+```sh
git checkout -b conflicts_branch
# vi conflicts.rb
@@ -49,7 +43,7 @@ git push origin master
Create a merge request on the GitLab web UI. You'll see a conflict warning.
-```
+```sh
git checkout conflicts_branch
git fetch
git rebase master
@@ -65,7 +59,6 @@ git rebase --continue
# need to force push so that our remote branch is restructured
git push origin conflicts_branch -f
```
-----------
## Note
diff --git a/doc/university/training/topics/merge_requests.md b/doc/university/training/topics/merge_requests.md
index d7b771cd87b..b5bbe7b2e1e 100644
--- a/doc/university/training/topics/merge_requests.md
+++ b/doc/university/training/topics/merge_requests.md
@@ -4,8 +4,6 @@ comments: false
# Code review and collaboration with Merge Requests
-----------
-
- When you want feedback create a merge request
- Target is the default branch (usually master)
- Assign or mention the person you would like to review
@@ -14,8 +12,6 @@ comments: false
- Anyone can comment, not just the assignee
- Push corrections to the same branch
-----------
-
## Merge requests
**Create your first merge request**
@@ -25,8 +21,6 @@ comments: false
1. Push a new commit to the same branch
1. Review the changes again and notice the update
-----------
-
## Feedback and Collaboration
- Merge requests are a time for feedback and collaboration
@@ -36,8 +30,6 @@ comments: false
- Be as receptive as possible
- Feedback is about the best code, not the person. You are not your code
-----------
-
## Feedback and Collaboration
Review the Thoughtbot code-review guide for suggestions to follow when reviewing merge requests:
diff --git a/doc/university/training/topics/rollback_commits.md b/doc/university/training/topics/rollback_commits.md
index 96b89e3319a..1e6602deef2 100644
--- a/doc/university/training/topics/rollback_commits.md
+++ b/doc/university/training/topics/rollback_commits.md
@@ -4,40 +4,34 @@ comments: false
# Rollback Commits
-----------
-
## Undo Commits
- Undo last commit putting everything back into the staging area:
- ```
+ ```sh
git reset --soft HEAD^
```
- Add files and change message with:
- ```
+ ```sh
git commit --amend -m "New Message"
```
-----------
-
- Undo last and remove changes:
- ```
+ ```sh
git reset --hard HEAD^
```
- Same as last one but for two commits back:
- ```
+ ```sh
git reset --hard HEAD^^
```
** Don't reset after pushing **
-----------
-
## Reset Workflow
1. Edit file again 'edit_this_file.rb'
@@ -51,11 +45,9 @@ comments: false
1. Pull for updates
1. Push changes
-----------
-
## Commands
-```
+```sh
# Change file edit_this_file.rb
git status
git commit -am "kjkfjkg"
@@ -68,15 +60,13 @@ git pull origin master
git push origin master
```
-----------
-
## Note
- git revert vs git reset
- Reset removes the commit while revert removes the changes but leaves the commit
- Revert is safer considering we can revert a revert
-```
+```sh
# Changed file
git commit -am "bug introduced"
git revert HEAD
diff --git a/doc/university/training/topics/stash.md b/doc/university/training/topics/stash.md
index dfd28fbcbc9..02b2f610266 100644
--- a/doc/university/training/topics/stash.md
+++ b/doc/university/training/topics/stash.md
@@ -4,14 +4,12 @@ comments: false
# Git Stash
-----------
-
We use git stash to store our changes when they are not ready to be committed
and we need to change to a different branch.
- Stash:
- ```
+ ```sh
git stash save
# or
git stash
@@ -21,18 +19,16 @@ and we need to change to a different branch.
- Apply stash to keep working on it:
- ```
+ ```sh
git stash apply
# or apply a specific one from out stack
git stash apply stash@{3}
```
-----------
-
- Every time we save a stash it gets stacked so by using list we can see all our
stashes.
- ```
+ ```sh
git stash list
# or for more information (log methods)
git stash list --stat
@@ -40,7 +36,7 @@ and we need to change to a different branch.
- To clean our stack we need to manually remove them:
- ```
+ ```sh
# drop top stash
git stash drop
# or
@@ -49,19 +45,15 @@ and we need to change to a different branch.
git stash clear
```
-----------
-
- Apply and drop on one command:
- ```
+ ```sh
git stash pop
```
- If we meet conflicts we need to either reset or commit our changes.
- Conflicts through `pop` will not drop a stash afterwards.
-----------
-
## Git Stash
1. Modify a file
@@ -72,11 +64,9 @@ and we need to change to a different branch.
1. Apply with pop
1. View list to confirm changes
-----------
-
## Commands
-```
+```sh
# Modify edit_this_file.rb file
git add .
diff --git a/doc/university/training/topics/subtree.md b/doc/university/training/topics/subtree.md
index ba7c3394938..981918d4758 100644
--- a/doc/university/training/topics/subtree.md
+++ b/doc/university/training/topics/subtree.md
@@ -9,19 +9,15 @@ comments: false
- For these cases we need a dependency control system.
- Command are painfully long so aliases are necessary.
-----------
-
## Subtree Aliases
-- Add: git subtree add --prefix <target-folder> <url> <branch> --squash.
-- Pull: git subtree add --prefix <target-folder> <url> <branch> --squash.
-- Push: git subtree add --prefix <target-folder> <url> <branch>.
-- Ex: git config alias.sbp 'subtree pull --prefix st /
- git@gitlab.com:balameb/subtree-nested-example.git master --squash'.
-
-----------
+- Add: `git subtree add --prefix <target-folder> <url> <branch> --squash`.
+- Pull: `git subtree add --prefix <target-folder> <url> <branch> --squash`.
+- Push: `git subtree add --prefix <target-folder> <url> <branch>`.
+- Ex: `git config alias.sbp 'subtree pull --prefix st /
+ git@gitlab.com:balameb/subtree-nested-example.git master --squash'`.
-```
+```sh
# Add an alias
# Add
git config alias.sba 'subtree add --prefix st /
@@ -41,9 +37,7 @@ comments: false
```
-----------
-
-```
+```sh
# Adding, or committing won't change the sub repo at remote
# even if we push
git add -A
diff --git a/doc/university/training/topics/tags.md b/doc/university/training/topics/tags.md
index 14c39457838..cdbb8a2da7c 100644
--- a/doc/university/training/topics/tags.md
+++ b/doc/university/training/topics/tags.md
@@ -1,19 +1,16 @@
---
comments: false
+type: reference
---
# Tags
-----------
-
- Useful for marking deployments and releases
- Annotated tags are an unchangeable part of Git history
- Soft/lightweight tags can be set and removed at will
- Many projects combine an annotated release tag with a stable branch
- Consider setting deployment/release tags automatically
-----------
-
# Tags
- Create a lightweight tag
@@ -24,11 +21,9 @@ comments: false
<https://git-scm.com/book/en/Git-Basics-Tagging>
-----------
-
# Commands
-```
+```sh
git checkout master
# Lightweight tag
@@ -40,3 +35,15 @@ git tag
git push origin --tags
```
+
+<!-- ## Troubleshooting
+
+Include any troubleshooting steps that you can foresee. If you know beforehand what issues
+one might have when setting this up, or when something is changed, or on upgrading, it's
+important to describe those, too. Think of things that may go wrong and include them here.
+This is important to minimize requests for support, and to avoid doc comments with
+questions that you know someone might ask.
+
+Each scenario can be a third-level heading, e.g. `### Getting error message X`.
+If you have none to add when creating a doc, leave this section in place
+but commented out to help encourage others to add to it in the future. -->
diff --git a/doc/university/training/topics/unstage.md b/doc/university/training/topics/unstage.md
index c926f0b4888..af16afdc5d1 100644
--- a/doc/university/training/topics/unstage.md
+++ b/doc/university/training/topics/unstage.md
@@ -4,8 +4,6 @@ comments: false
# Unstage
-----------
-
## Unstage
- To remove files from stage use reset HEAD where HEAD is the last commit of the current branch. This will unstage the file but maintain the modifications.
@@ -20,17 +18,15 @@ comments: false
git checkout -- <file>
```
-----------
-
- To remove a file from disk and repo use 'git rm' and to rm a dir use the '-r' flag:
- ```
+ ```sh
git rm '*.txt'
git rm -r <dirname>
```
- If we want to remove a file from the repository but keep it on disk, say we forgot to add it to our `.gitignore` file then use `--cache`:
- ```
+ ```sh
git rm <filename> --cache
```
diff --git a/doc/university/training/user_training.md b/doc/university/training/user_training.md
index ca3f777f403..e440652edfc 100644
--- a/doc/university/training/user_training.md
+++ b/doc/university/training/user_training.md
@@ -1,11 +1,10 @@
---
comments: false
+type: reference
---
# GitLab Git Workshop
----
-
## Agenda
1. Brief history of Git.
@@ -13,8 +12,6 @@ comments: false
1. Configure your environment.
1. Workshop.
----
-
## Git introduction
<https://git-scm.com/about>
@@ -26,8 +23,6 @@ comments: false
- Adapts to nearly any workflow.
- Fast, reliable and stable file format.
----
-
## Help!
Use the tools at your disposal when you get stuck.
@@ -36,14 +31,10 @@ Use the tools at your disposal when you get stuck.
- Use Google.
- Read documentation at <https://git-scm.com>.
----
-
## GitLab Walkthrough
![fit](logo.png)
----
-
## Configure your environment
- Windows: Install 'Git for Windows'
@@ -56,8 +47,6 @@ Use the tools at your disposal when you get stuck.
- Debian: '`sudo apt-get install git-all`' or Red Hat '`sudo yum install git-all`'
----
-
## Git Workshop
### Overview
@@ -70,8 +59,6 @@ Use the tools at your disposal when you get stuck.
1. Merge requests.
1. Feedback and Collaboration.
----
-
## Configure Git
One-time configuration of the Git client:
@@ -81,8 +68,6 @@ git config --global user.name "Your Name"
git config --global user.email you@example.com
```
----
-
## Configure SSH Key
```sh
@@ -111,8 +96,6 @@ cat ~/.ssh/id_rsa.pub
ssh-rsa AAAAB3NzaC1yc2EAAAADAQEL17Ufacg8cDhlQMS5NhV8z3GHZdhCrZbl4gz you@example.com
```
----
-
## Create a project
- Create a project in your user namespace.
@@ -120,8 +103,6 @@ ssh-rsa AAAAB3NzaC1yc2EAAAADAQEL17Ufacg8cDhlQMS5NhV8z3GHZdhCrZbl4gz you@example.
- Create a '`development`' or '`workspace`' directory in your home directory.
- Clone the '`training-examples`' project.
----
-
## Commands (project)
```sh
@@ -137,8 +118,6 @@ git clone git@gitlab.example.com:<username>/training-examples.git
cd training-examples
```
----
-
## Git concepts
### Untracked files
@@ -153,8 +132,6 @@ Files that have been modified but are not committed.
Modified files that have been marked to go in the next commit.
----
-
## Committing
1. Edit '`edit_this_file.rb`' in '`training-examples`'.
@@ -165,8 +142,6 @@ Modified files that have been marked to go in the next commit.
1. Push the commit to the remote.
1. View the git log.
----
-
## Commands (committing)
```sh
@@ -179,8 +154,6 @@ git push origin master
git log
```
----
-
## Feature branching
- Efficient parallel workflow for teams.
@@ -190,8 +163,6 @@ git log
- Push branches to the server frequently.
- Hint: This is a cheap backup for your work-in-progress code.
----
-
## Feature branching steps
1. Create a new feature branch called 'squash_some_bugs'.
@@ -199,8 +170,6 @@ git log
1. Commit.
1. Push.
----
-
## Commands (feature branching)
```sh
@@ -212,8 +181,6 @@ git commit -m 'Fix some buggy code'
git push origin squash_some_bugs
```
----
-
## Merge requests
- When you want feedback create a merge request.
@@ -224,8 +191,6 @@ git push origin squash_some_bugs
- Anyone can comment, not just the assignee.
- Push corrections to the same branch.
----
-
## Merge requests steps
Create your first merge request:
@@ -235,8 +200,6 @@ Create your first merge request:
1. Push a new commit to the same branch.
1. Review the changes again and notice the update.
----
-
## Feedback and Collaboration
- Merge requests are a time for feedback and collaboration.
@@ -246,8 +209,6 @@ Create your first merge request:
- Be as receptive as possible.
- Feedback is about the best code, not the person. You are not your code.
----
-
## Feedback and Collaboration resources
Review the Thoughtbot code-review guide for suggestions to follow when reviewing merge requests:
@@ -255,8 +216,6 @@ Review the Thoughtbot code-review guide for suggestions to follow when reviewing
See GitLab merge requests for examples: <https://gitlab.com/gitlab-org/gitlab-ce/merge_requests>.
----
-
## Explore GitLab projects
![fit](logo.png)
@@ -269,8 +228,6 @@ See GitLab merge requests for examples: <https://gitlab.com/gitlab-org/gitlab-ce
- Manage project members
- Project settings
----
-
## Tags
- Useful for marking deployments and releases.
@@ -279,8 +236,6 @@ See GitLab merge requests for examples: <https://gitlab.com/gitlab-org/gitlab-ce
- Many projects combine an annotated release tag with a stable branch.
- Consider setting deployment/release tags automatically.
----
-
## Tags steps
1. Create a lightweight tag.
@@ -289,8 +244,6 @@ See GitLab merge requests for examples: <https://gitlab.com/gitlab-org/gitlab-ce
Additional resources: <http://git-scm.com/book/en/Git-Basics-Tagging>.
----
-
## Commands (tags)
```sh
@@ -306,8 +259,6 @@ git tag
git push origin --tags
```
----
-
## Merge conflicts
- Happen often.
@@ -315,8 +266,6 @@ git push origin --tags
- Practice makes perfect.
- Force push after fixing conflicts. Be careful!
----
-
## Merge conflicts steps
1. Checkout a new branch and edit `conflicts.rb`. Add 'Line4' and 'Line5'.
@@ -325,8 +274,6 @@ git push origin --tags
1. Commit and push to master.
1. Create a merge request.
----
-
## Merge conflicts commands
After creating a merge request you should notice that conflicts exist. Resolve
@@ -343,8 +290,6 @@ git rebase --continue
git push origin <branch> -f
```
----
-
## Rebase with squash
You may end up with a commit log that looks like this:
@@ -361,8 +306,6 @@ Does this work?
Squash these in to meaningful commits using an interactive rebase.
----
-
## Rebase with squash commands
Squash the commits on the same branch we used for the merge conflicts step.
@@ -373,8 +316,6 @@ git rebase -i master
In the editor, leave the first commit as 'pick' and set others to 'fixup'.
----
-
## Questions?
![fit](logo.png)
@@ -383,9 +324,16 @@ Thank you for your hard work!
## Additional Resources
-- GitLab Documentation: <http://docs.gitlab.com/>.
-- GUI Clients: <http://git-scm.com/downloads/guis>.
-- Pro Git book: <http://git-scm.com/book>.
-- Platzi Course: <https://courses.platzi.com/courses/git-gitlab/>.
-- Code School tutorial: <http://try.github.io/>.
-- Contact us at `subscribers@gitlab.com`.
+See [additional resources](index.md#additional-resources).
+
+<!-- ## Troubleshooting
+
+Include any troubleshooting steps that you can foresee. If you know beforehand what issues
+one might have when setting this up, or when something is changed, or on upgrading, it's
+important to describe those, too. Think of things that may go wrong and include them here.
+This is important to minimize requests for support, and to avoid doc comments with
+questions that you know someone might ask.
+
+Each scenario can be a third-level heading, e.g. `### Getting error message X`.
+If you have none to add when creating a doc, leave this section in place
+but commented out to help encourage others to add to it in the future. -->
diff --git a/doc/update/upgrading_from_source.md b/doc/update/upgrading_from_source.md
index f82d666c7be..bc8e5fed774 100644
--- a/doc/update/upgrading_from_source.md
+++ b/doc/update/upgrading_from_source.md
@@ -107,11 +107,11 @@ Download and install Go:
# Remove former Go installation folder
sudo rm -rf /usr/local/go
-curl --remote-name --progress https://dl.google.com/go/go1.10.5.linux-amd64.tar.gz
-echo 'a035d9beda8341b645d3f45a1b620cf2d8fb0c5eb409be36b389c0fd384ecc3a go1.10.5.linux-amd64.tar.gz' | shasum -a256 -c - && \
- sudo tar -C /usr/local -xzf go1.10.5.linux-amd64.tar.gz
+curl --remote-name --progress https://dl.google.com/go/go1.11.10.linux-amd64.tar.gz
+echo 'aefaa228b68641e266d1f23f1d95dba33f17552ba132878b65bb798ffa37e6d0 go1.11.10.linux-amd64.tar.gz' | shasum -a256 -c - && \
+ sudo tar -C /usr/local -xzf go1.11.10.linux-amd64.tar.gz
sudo ln -sf /usr/local/go/bin/{go,godoc,gofmt} /usr/local/bin/
-rm go1.10.5.linux-amd64.tar.gz
+rm go1.11.10.linux-amd64.tar.gz
```
### 6. Update git
diff --git a/doc/user/admin_area/index.md b/doc/user/admin_area/index.md
index 527110d53df..91c771764f8 100644
--- a/doc/user/admin_area/index.md
+++ b/doc/user/admin_area/index.md
@@ -20,7 +20,7 @@ The Admin Area is made up of the following sections:
| Section | Description |
|:---------------------------|:---------------------------------------------------------------------------------------------------------------------------------------------------------|
-| Overview | View your GitLab [Dashboard](#admin-dashboard), and administer [projects](#administer-projects), [users](#administer-users), groups, [jobs](#administer-jobs), [Runners](#administer-runners), and [Gitaly servers](#administer-gitaly-servers). |
+| Overview | View your GitLab [Dashboard](#admin-dashboard), and administer [projects](#administer-projects), [users](#administer-users), [groups](#administer-groups), [jobs](#administer-jobs), [Runners](#administer-runners), and [Gitaly servers](#administer-gitaly-servers). |
| Monitoring | View GitLab system information, and information on background jobs, logs, [health checks](monitoring/health_check.md), request profiles, and audit logs. |
| Messages | Send and manage [broadcast messages](broadcast_messages.md) for your users. |
| System Hooks | Configure [system hooks](../../system_hooks/system_hooks.md) for many events. |
@@ -120,13 +120,32 @@ To search for users, enter your criteria in the search field. The user search is
insensitive, and applies partial matching to name and username. To search for an email address,
you must provide the complete email address.
+## Administer Groups
+
+You can administer all groups in the GitLab instance from the Admin Area's Groups page.
+
+To access the Groups page, go to **Admin Area > Overview > Groups**.
+
+For each group, the page displays their name, description, size, number of projects in the group,
+number of members, and whether the group is private, internal, or public. To edit a group, click
+the **Edit** button in that group's row. To delete the group, click the **Delete** button in
+that group's row.
+
+To change the sort order, click the sort dropdown and select the desired order. The default
+sort order is by **Last created**.
+
+To search for groups by name, enter your criteria in the search field. The group search is case
+insensitive, and applies partial matching.
+
+To [Create a new group](../group/index.md#create-a-new-group) click **New group**.
+
## Administer Jobs
You can administer all jobs in the GitLab instance from the Admin Area's Jobs page.
To access the Jobs page, go to **Admin Area > Overview > Jobs**.
-All jobs are listed, in reverse order of their job ID.
+All jobs are listed, in descending order of job ID.
Click the **All** tab to list all jobs. Click the **Pending**, **Running**, or **Finished** tab to list only jobs of that status.
@@ -169,7 +188,7 @@ find.
You can also filter Runners by status, type, and tag. To filter:
1. Click in the **Search or filter results...** field.
-1. Select **status:**, **type:**, or **tag:**
+1. Select **status:**, **type:**, or **tag:**.
1. Select or enter your search criteria.
![Attributes of a Runner, with the **Search or filter results...** field active](img/index_runners_search_or_filter.png)
diff --git a/doc/user/admin_area/license.md b/doc/user/admin_area/license.md
index 1e8ce04da92..8ddb9c3d707 100644
--- a/doc/user/admin_area/license.md
+++ b/doc/user/admin_area/license.md
@@ -49,16 +49,10 @@ Otherwise, you can:
## Add your license at install time
-The license may be automatically injected during installation using one of
-two methods.
+A license can be automatically imported at install time, by placing a file named
+`Gitlab.gitlab-license` in `/etc/gitlab/` for Omnibus, or `config/` for source installations.
-The first requires a license file named `Gitlab.gitlab-release`.
-
-Place it in the `config/` directory if installing from source or in the
-`/etc/gitlab/` directory if installing Omnibus.
-
-The second allows the administrator to configure the location and
-filename of the license.
+It is also possible to specify a custom location and filename for the license.
Source installations should set the `GITLAB_LICENSE_FILE` environment
variable with the path to a valid GitLab Enterprise Edition license.
diff --git a/doc/user/admin_area/monitoring/health_check.md b/doc/user/admin_area/monitoring/health_check.md
index ff056490653..f80d4e9d2aa 100644
--- a/doc/user/admin_area/monitoring/health_check.md
+++ b/doc/user/admin_area/monitoring/health_check.md
@@ -6,7 +6,7 @@ type: concepts, howto
> - Liveness and readiness probes were [introduced][ce-10416] in GitLab 9.1.
> - The `health_check` endpoint was [introduced][ce-3888] in GitLab 8.8 and was
-> be deprecated in GitLab 9.1.
+> deprecated in GitLab 9.1.
> - [Access token](#access-token-deprecated) has been deprecated in GitLab 9.4
> in favor of [IP whitelist](#ip-whitelist).
diff --git a/doc/user/application_security/container_scanning/index.md b/doc/user/application_security/container_scanning/index.md
index adb6868516e..a24374dff1d 100644
--- a/doc/user/application_security/container_scanning/index.md
+++ b/doc/user/application_security/container_scanning/index.md
@@ -12,7 +12,7 @@ two open source tools for Vulnerability Static Analysis for containers.
You can take advantage of Container Scanning by either [including the CI job](#including-the-provided-template) in
your existing `.gitlab-ci.yml` file or by implicitly using
-[Auto Container Scanning](../../../topics/autodevops/index.md#auto-container-scanning)
+[Auto Container Scanning](../../../topics/autodevops/index.md#auto-container-scanning-ultimate)
that is provided by [Auto DevOps](../../../topics/autodevops/index.md).
GitLab checks the Container Scanning report, compares the found vulnerabilities
diff --git a/doc/user/application_security/dependency_scanning/index.md b/doc/user/application_security/dependency_scanning/index.md
index d78cf778110..c65f369244a 100644
--- a/doc/user/application_security/dependency_scanning/index.md
+++ b/doc/user/application_security/dependency_scanning/index.md
@@ -214,6 +214,159 @@ dependency_scanning:
paths: [gl-dependency-scanning-report.json]
```
+## Reports JSON format
+
+CAUTION: **Caution:**
+The JSON report artifacts are not a public API of Dependency Scanning and their format may change in future.
+
+The Dependency Scanning tool emits a JSON report file. Here is an example of a structure for a report will all important parts of
+it highlighted:
+
+```json-doc
+{
+ "version": "2.0",
+ "vulnerabilities": [
+ {
+ "category": "dependency_scanning",
+ "name": "Regular Expression Denial of Service",
+ "message": "Regular Expression Denial of Service in debug",
+ "description": "The debug module is vulnerable to regular expression denial of service when untrusted user input is passed into the `o` formatter. It takes around 50k characters to block for 2 seconds making this a low severity issue.",
+ "cve": "yarn.lock:debug:gemnasium:37283ed4-0380-40d7-ada7-2d994afcc62a",
+ "severity": "Unknown",
+ "solution": "Upgrade to latest versions.",
+ "scanner": {
+ "id": "gemnasium",
+ "name": "Gemnasium"
+ },
+ "location": {
+ "file": "yarn.lock",
+ "dependency": {
+ "package": {
+ "name": "debug"
+ },
+ "version": "1.0.5"
+ }
+ },
+ "identifiers": [
+ {
+ "type": "gemnasium",
+ "name": "Gemnasium-37283ed4-0380-40d7-ada7-2d994afcc62a",
+ "value": "37283ed4-0380-40d7-ada7-2d994afcc62a",
+ "url": "https://deps.sec.gitlab.com/packages/npm/debug/versions/1.0.5/advisories"
+ }
+ ],
+ "links": [
+ {
+ "url": "https://nodesecurity.io/advisories/534"
+ },
+ {
+ "url": "https://github.com/visionmedia/debug/issues/501"
+ },
+ {
+ "url": "https://github.com/visionmedia/debug/pull/504"
+ }
+ ]
+ },
+ {
+ "category": "dependency_scanning",
+ "name": "Authentication bypass via incorrect DOM traversal and canonicalization",
+ "message": "Authentication bypass via incorrect DOM traversal and canonicalization in saml2-js",
+ "description": "Some XML DOM traversal and canonicalization APIs may be inconsistent in handling of comments within XML nodes. Incorrect use of these APIs by some SAML libraries results in incorrect parsing of the inner text of XML nodes such that any inner text after the comment is lost prior to cryptographically signing the SAML message. Text after the comment therefore has no impact on the signature on the SAML message.\r\n\r\nA remote attacker can modify SAML content for a SAML service provider without invalidating the cryptographic signature, which may allow attackers to bypass primary authentication for the affected SAML service provider.",
+ "cve": "yarn.lock:saml2-js:gemnasium:9952e574-7b5b-46fa-a270-aeb694198a98",
+ "severity": "Unknown",
+ "solution": "Upgrade to fixed version.\r\n",
+ "scanner": {
+ "id": "gemnasium",
+ "name": "Gemnasium"
+ },
+ "location": {
+ "file": "yarn.lock",
+ "dependency": {
+ "package": {
+ "name": "saml2-js"
+ },
+ "version": "1.5.0"
+ }
+ },
+ "identifiers": [
+ {
+ "type": "gemnasium",
+ "name": "Gemnasium-9952e574-7b5b-46fa-a270-aeb694198a98",
+ "value": "9952e574-7b5b-46fa-a270-aeb694198a98",
+ "url": "https://deps.sec.gitlab.com/packages/npm/saml2-js/versions/1.5.0/advisories"
+ },
+ {
+ "type": "cve",
+ "name": "CVE-2017-11429",
+ "value": "CVE-2017-11429",
+ "url": "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-11429"
+ }
+ ],
+ "links": [
+ {
+ "url": "https://github.com/Clever/saml2/commit/3546cb61fd541f219abda364c5b919633609ef3d#diff-af730f9f738de1c9ad87596df3f6de84R279"
+ },
+ {
+ "url": "https://github.com/Clever/saml2/issues/127"
+ },
+ {
+ "url": "https://www.kb.cert.org/vuls/id/475445"
+ }
+ ]
+ }
+ ],
+ "remediations": [
+ {
+ "fixes": [
+ {
+ "cve": "yarn.lock:saml2-js:gemnasium:9952e574-7b5b-46fa-a270-aeb694198a98"
+ }
+ ],
+ "summary": "Upgrade saml2-js",
+ "diff": "ZGlmZiAtLWdpdCBhL...OR0d1ZUc2THh3UT09Cg==" // some content is omitted for brevity
+ }
+ ]
+}
+```
+
+Here is the description of the report file structure nodes and their meaning. All fields are mandatory to be present in
+the report JSON unless stated otherwise. Presence of optional fields depends on the underlying analyzers being used.
+
+| Report JSON node | Function |
+|------------------------------------------------------|----------|
+| `version` | Report syntax version used to generate this JSON. |
+| `vulnerabilities` | Array of vulnerability objects. |
+| `vulnerabilities[].category` | Where this vulnerability belongs (SAST, Dependency Scanning etc.). For Dependency Scanning, it will always be `dependency_scanning`. |
+| `vulnerabilities[].name` | Name of the vulnerability, this must not include the occurrence's specific information. Optional. |
+| `vulnerabilities[].message` | A short text that describes the vulnerability, it may include occurrence's specific information. Optional. |
+| `vulnerabilities[].description` | A long text that describes the vulnerability. Optional. |
+| `vulnerabilities[].cve` | A fingerprint string value that represents a concrete occurrence of the vulnerability. It's used to determine whether two vulnerability occurrences are same or different. May not be 100% accurate. **This is NOT a [CVE](https://cve.mitre.org/)**. |
+| `vulnerabilities[].severity` | How much the vulnerability impacts the software. Possible values: `Undefined` (an analyzer has not provided this info), `Info`, `Unknown`, `Low`, `Medium`, `High`, `Critical`. |
+| `vulnerabilities[].confidence` | How reliable the vulnerability's assessment is. Possible values: `Undefined` (an analyzer has not provided this info), `Ignore`, `Unknown`, `Experimental`, `Low`, `Medium`, `High`, `Confirmed`. |
+| `vulnerabilities[].solution` | Explanation of how to fix the vulnerability. Optional. |
+| `vulnerabilities[].scanner` | A node that describes the analyzer used find this vulnerability. |
+| `vulnerabilities[].scanner.id` | Id of the scanner as a snake_case string. |
+| `vulnerabilities[].scanner.name` | Name of the scanner, for display purposes. |
+| `vulnerabilities[].location` | A node that tells which class and/or method is affected by the vulnerability. |
+| `vulnerabilities[].location.file` | Path to the dependencies file (e.g., `yarn.lock`). Optional. |
+| `vulnerabilities[].location.dependency` | A node that describes the dependency of a project where the vulnerability is located. |
+| `vulnerabilities[].location.dependency.package` | A node that provides the information on the package where the vulnerability is located. |
+| `vulnerabilities[].location.dependency.package.name` | Name of the package where the vulnerability is located. Optional. |
+| `vulnerabilities[].location.dependency.version` | Version of the vulnerable package. Optional. |
+| `vulnerabilities[].identifiers` | An ordered array of references that identify a vulnerability on internal or external DBs. |
+| `vulnerabilities[].identifiers[].type` | Type of the identifier. Possible values: common identifier types (among `cve`, `cwe`, `osvdb`, and `usn`) or analyzer-dependent ones (e.g. `gemnasium` for [Gemnasium](https://gitlab.com/gitlab-org/security-products/analyzers/gemnasium/)). |
+| `vulnerabilities[].identifiers[].name` | Name of the identifier for display purpose. |
+| `vulnerabilities[].identifiers[].value` | Value of the identifier for matching purpose. |
+| `vulnerabilities[].identifiers[].url` | URL to identifier's documentation. Optional. |
+| `vulnerabilities[].links` | An array of references to external documentation pieces or articles that describe the vulnerability further. Optional. |
+| `vulnerabilities[].links[].name` | Name of the vulnerability details link. Optional. |
+| `vulnerabilities[].links[].url` | URL of the vulnerability details document. Optional. |
+| `remediations` | An array of objects containing information on cured vulnerabilities along with patch diffs to apply. |
+| `remediations[].fixes` | An array of strings that represent references to vulnerabilities fixed by this particular remediation. |
+| `remediations[].fixes[].cve` | A string value that describes a fixed vulnerability occurrence in the same format as `vulnerabilities[].cve`. |
+| `remediations[].summary` | Overview of how the vulnerabilities have been fixed. |
+| `remediations[].diff` | base64-encoded remediation code diff, compatible with [`git apply`](https://git-scm.com/docs/git-format-patch#_discussion). |
+
## Security Dashboard
The Security Dashboard is a good place to get an overview of all the security
diff --git a/doc/user/application_security/sast/index.md b/doc/user/application_security/sast/index.md
index db328262aba..19befb04b76 100644
--- a/doc/user/application_security/sast/index.md
+++ b/doc/user/application_security/sast/index.md
@@ -191,7 +191,7 @@ sast:
You can supply many other [settings variables](https://gitlab.com/gitlab-org/security-products/sast#settings)
via `docker run --env` to customize your job execution.
-## Manual job definition for GitLab 11.4 and earlier (deprecated)
+### Manual job definition for GitLab 11.4 and earlier (deprecated)
CAUTION: **Deprecated:**
Before GitLab 11.5, the SAST job and artifact had to be named specifically
@@ -221,6 +221,118 @@ sast:
paths: [gl-sast-report.json]
```
+## Reports JSON format
+
+CAUTION: **Caution:**
+The JSON report artifacts are not a public API of SAST and their format may change in the future.
+
+The SAST tool emits a JSON report report file. Here is an example of a structure for a report will all important parts of
+it highlighted:
+
+```json-doc
+{
+ "version": "2.0",
+ "vulnerabilities": [
+ {
+ "category": "sast",
+ "name": "Predictable pseudorandom number generator",
+ "message": "Predictable pseudorandom number generator",
+ "description": "The use of java.util.Random is predictable",
+ "cve": "818bf5dacb291e15d9e6dc3c5ac32178:PREDICTABLE_RANDOM",
+ "severity": "Medium",
+ "confidence": "Medium",
+ "scanner": {
+ "id": "find_sec_bugs",
+ "name": "Find Security Bugs"
+ },
+ "location": {
+ "file": "groovy/src/main/groovy/com/gitlab/security_products/tests/App.groovy",
+ "start_line": 47,
+ "end_line": 47,
+ "class": "com.gitlab.security_products.tests.App",
+ "method": "generateSecretToken2",
+ "dependency": {
+ "package": {}
+ }
+ },
+ "identifiers": [
+ {
+ "type": "find_sec_bugs_type",
+ "name": "Find Security Bugs-PREDICTABLE_RANDOM",
+ "value": "PREDICTABLE_RANDOM",
+ "url": "https://find-sec-bugs.github.io/bugs.htm#PREDICTABLE_RANDOM"
+ },
+ {
+ "type": "cwe",
+ "name": "CWE-330",
+ "value": "330",
+ "url": "https://cwe.mitre.org/data/definitions/330.html"
+ }
+ ]
+ },
+ {
+ "category": "sast",
+ // "name" may be omitted because it could be not reported by a particular analyzer
+ "message": "Probable insecure usage of temp file/directory.",
+ "cve": "python/hardcoded/hardcoded-tmp.py:4ad6d4c40a8c263fc265f3384724014e0a4f8dd6200af83e51ff120420038031:B108",
+ "severity": "Medium",
+ "confidence": "Medium",
+ "scanner": {
+ "id": "bandit",
+ "name": "Bandit"
+ },
+ "location": {
+ "file": "python/hardcoded/hardcoded-tmp.py",
+ "start_line": 10,
+ "end_line": 10,
+ "dependency": {
+ "package": {}
+ }
+ },
+ "identifiers": [
+ {
+ "type": "bandit_test_id",
+ "name": "Bandit Test ID B108",
+ "value": "B108",
+ "url": "https://docs.openstack.org/bandit/latest/plugins/b108_hardcoded_tmp_directory.html"
+ }
+ ]
+ },
+ ],
+ "remediations": []
+}
+```
+
+Here is the description of the report file structure nodes and their meaning. All fields are mandatory to be present in
+the report JSON unless stated otherwise. Presence of optional fields depends on the underlying analyzers being used.
+
+| Report JSON node | Function |
+|-----------------------------------------|----------|
+| `version` | Report syntax version used to generate this JSON. |
+| `vulnerabilities` | Array of vulnerability objects. |
+| `vulnerabilities[].category` | Where this vulnerability belongs (SAST, Dependency Scanning etc.). For SAST, it will always be `sast`. |
+| `vulnerabilities[].name` | Name of the vulnerability, this must not include the occurrence's specific information. Optional. |
+| `vulnerabilities[].message` | A short text that describes the vulnerability, it may include the occurrence's specific information. Optional. |
+| `vulnerabilities[].description` | A long text that describes the vulnerability. Optional. |
+| `vulnerabilities[].cve` | A fingerprint string value that represents a concrete occurrence of the vulnerability. Is used to determine whether two vulnerability occurrences are same or different. May not be 100% accurate. **This is NOT a [CVE](https://cve.mitre.org/)**. |
+| `vulnerabilities[].severity` | How much the vulnerability impacts the software. Possible values: `Undefined` (an analyzer has not provided this info), `Info`, `Unknown`, `Low`, `Medium`, `High`, `Critical`. |
+| `vulnerabilities[].confidence` | How reliable the vulnerability's assessment is. Possible values: `Undefined` (an analyzer has not provided this info), `Ignore`, `Unknown`, `Experimental`, `Low`, `Medium`, `High`, `Confirmed`. |
+| `vulnerabilities[].solution` | Explanation of how to fix the vulnerability. Optional. |
+| `vulnerabilities[].scanner` | A node that describes the analyzer used find this vulnerability. |
+| `vulnerabilities[].scanner.id` | Id of the scanner as a snake_case string. |
+| `vulnerabilities[].scanner.name` | Name of the scanner, for display purposes. |
+| `vulnerabilities[].location` | A node that tells which class and/or method is affected by the vulnerability. |
+| `vulnerabilities[].location.file` | Path to the file where the vulnerability is located. Optional. |
+| `vulnerabilities[].location.start_line` | The first line of the code affected by the vulnerability. Optional. |
+| `vulnerabilities[].location.end_line` | The last line of the code affected by the vulnerability. Optional. |
+| `vulnerabilities[].location.class` | If specified, provides the name of the class where the vulnerability is located. Optional. |
+| `vulnerabilities[].location.method` | If specified, provides the name of the method where the vulnerability is located. Optional. |
+| `vulnerabilities[].identifiers` | An ordered array of references that identify a vulnerability on internal or external DBs. |
+| `vulnerabilities[].identifiers[].type` | Type of the identifier. Possible values: common identifier types (among `cve`, `cwe`, `osvdb`, and `usn`) or analyzer-dependent ones (e.g., `bandit_test_id` for [Bandit analyzer](https://wiki.openstack.org/wiki/Security/Projects/Bandit)). |
+| `vulnerabilities[].identifiers[].name` | Name of the identifier for display purposes. |
+| `vulnerabilities[].identifiers[].value` | Value of the identifier for matching purposes. |
+| `vulnerabilities[].identifiers[].url` | URL to identifier's documentation. Optional. |
+
## Secret detection
GitLab is also able to detect secrets and credentials that have been unintentionally pushed to the repository.
diff --git a/doc/user/group/index.md b/doc/user/group/index.md
index 8335e532d0b..97d309caf7c 100644
--- a/doc/user/group/index.md
+++ b/doc/user/group/index.md
@@ -113,6 +113,8 @@ Add the following information:
1. Optionally, choose an avatar for your group.
1. Choose the [visibility level](../../public_access/public_access.md).
+For more details on creating groups, watch the video [GitLab Namespaces (users, groups and subgroups)](https://youtu.be/r0sJgjR2f5A).
+
## Add users to a group
A benefit of putting multiple projects in one group is that you can
@@ -215,10 +217,8 @@ Get an overview of the vulnerabilities of all the projects in a group and its su
## Insights **[ULTIMATE]**
-> Introduced in [GitLab Ultimate][ee] 11.9 behind the `insights` feature flag.
-
-Configure the Insights that matter for your groups or projects, allowing users to explore data
-such as:
+Configure the Insights that matter for your groups or projects, allowing users
+to explore data such as:
- Triage hygiene
- Issues created/closed per a given period
@@ -232,8 +232,8 @@ such as:
From GitLab 10.5, you can transfer groups in the following ways:
- Transfer a subgroup to a new parent group.
-- Convert a top-level group into a subgroup by transfering it to the desired group.
-- Convert a subgroup into a top-level group by transfering it out of its current group.
+- Convert a top-level group into a subgroup by transferring it to the desired group.
+- Convert a subgroup into a top-level group by transferring it out of its current group.
When transferring groups, note:
diff --git a/doc/user/group/insights/index.md b/doc/user/group/insights/index.md
index a4ea71074ec..1aba5d0986b 100644
--- a/doc/user/group/insights/index.md
+++ b/doc/user/group/insights/index.md
@@ -5,11 +5,7 @@ type: reference, howto
# Insights **[ULTIMATE]**
> Introduced in [GitLab Ultimate](https://about.gitlab.com/pricing/) 11.9 behind the `insights` feature flag.
-
-CAUTION: **Beta:**
-Insights is considered beta, and is not ready for production use.
-Follow [gitlab-org/quality/team-tasks#137](https://gitlab.com/gitlab-org/quality/team-tasks/issues/137#general-availability)
-for updates.
+> **Generally Available** (GA) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 12.0.
Configure the Insights that matter for your groups to explore data such as
triage hygiene, issues created/closed per a given period, average time for merge
diff --git a/doc/user/group/saml_sso/scim_setup.md b/doc/user/group/saml_sso/scim_setup.md
index c00628bf909..96cc523f4ec 100644
--- a/doc/user/group/saml_sso/scim_setup.md
+++ b/doc/user/group/saml_sso/scim_setup.md
@@ -1,7 +1,15 @@
+---
+type: howto, reference
+---
+
# SCIM provisioning using SAML SSO for Groups **[SILVER ONLY]**
> [Introduced](https://gitlab.com/gitlab-org/gitlab-ee/merge_requests/9388) in [GitLab.com Silver](https://about.gitlab.com/pricing/) 11.10.
+System for Cross-domain Identity Management (SCIM), is an open standard that enables the
+automation of user provisioning. When SCIM is provisioned for a GitLab group, membership of
+that group is synchronized between GitLab and the identity provider.
+
GitLab's [SCIM API](../../../api/scim.md) implements part of [the RFC7644 protocol](https://tools.ietf.org/html/rfc7644).
Currently, the following actions are available:
@@ -100,3 +108,15 @@ the `Provisioning Status` to `ON`.
Once enabled, the synchronization details and any errors will appear on the
bottom of the **Provisioning** screen, together with a link to the audit logs.
+
+<!-- ## Troubleshooting
+
+Include any troubleshooting steps that you can foresee. If you know beforehand what issues
+one might have when setting this up, or when something is changed, or on upgrading, it's
+important to describe those, too. Think of things that may go wrong and include them here.
+This is important to minimize requests for support, and to avoid doc comments with
+questions that you know someone might ask.
+
+Each scenario can be a third-level heading, e.g. `### Getting error message X`.
+If you have none to add when creating a doc, leave this section in place
+but commented out to help encourage others to add to it in the future. -->
diff --git a/doc/user/img/markdown_inline_diffs_tags_rendered.png b/doc/user/img/markdown_inline_diffs_tags_rendered.png
new file mode 100644
index 00000000000..4279a20b5a0
--- /dev/null
+++ b/doc/user/img/markdown_inline_diffs_tags_rendered.png
Binary files differ
diff --git a/doc/user/instance_statistics/convdev.md b/doc/user/instance_statistics/convdev.md
index 2c9e0ecbf65..d486ecc39a4 100644
--- a/doc/user/instance_statistics/convdev.md
+++ b/doc/user/instance_statistics/convdev.md
@@ -5,7 +5,7 @@
NOTE: **Note:**
Your GitLab instance's [usage ping](../admin_area/settings/usage_statistics.md#usage-ping-core-only) must be activated in order to use this feature.
-The Conversational Development Index (ConvDev Index) gives you an overview of your entire
+The [Conversational Development](http://conversationaldevelopment.com/2017/04/16/what-is-conversational-development/) Index (ConvDev Index) gives you an overview of your entire
instance's adoption of [Concurrent DevOps](https://about.gitlab.com/concurrent-devops/)
from planning to monitoring.
diff --git a/doc/user/markdown.md b/doc/user/markdown.md
index 6b6e5ab7634..31c8093ced7 100644
--- a/doc/user/markdown.md
+++ b/doc/user/markdown.md
@@ -246,7 +246,7 @@ https://gitlab.com/gitlab-org/gitlab-ce/blob/master/doc/user/markdown.md#inline-
With inline diffs tags you can display {+ additions +} or [- deletions -].
-The wrapping tags can be either curly braces or square brackets: [+ additions +] or {- deletions -}.
+The wrapping tags can be either curly braces or square brackets.
Examples:
@@ -257,6 +257,10 @@ Examples:
- [- deletions -]
```
+becomes:
+
+![inline diffs tags rendered](img/markdown_inline_diffs_tags_rendered.png)
+
However the wrapping tags cannot be mixed as such:
```
diff --git a/doc/user/project/cycle_analytics.md b/doc/user/project/cycle_analytics.md
index 19ab911e39f..dc97a44fd68 100644
--- a/doc/user/project/cycle_analytics.md
+++ b/doc/user/project/cycle_analytics.md
@@ -1,10 +1,7 @@
# Cycle Analytics
-> [Introduced][ce-5986] in GitLab 8.12. Further features were added in GitLab
- 8.14.
-
-Cycle Analytics measures the time spent to go from an [idea to production] for
-each of your projects. Cycle Analytics displays the median time for an idea to
+Cycle Analytics measures the time spent to go from an [idea to production] - also known
+as cycle time - for each of your projects. Cycle Analytics displays the median time for an idea to
reach production, along with the time typically spent in each DevOps stage along the way.
Cycle Analytics is useful in order to quickly determine the velocity of a given
@@ -54,9 +51,9 @@ Below you can see in more detail what the various stages of Cycle Analytics mean
| Issue | Measures the median time between creating an issue and taking action to solve it, by either labeling it or adding it to a milestone, whatever comes first. The label will be tracked only if it already has an [Issue Board list][board] created for it. |
| Plan | Measures the median time between the action you took for the previous stage, and pushing the first commit to the branch. The very first commit of the branch is the one that triggers the separation between **Plan** and **Code**, and at least one of the commits in the branch needs to contain the related issue number (e.g., `#42`). If none of the commits in the branch mention the related issue number, it is not considered to the measurement time of the stage. |
| Code | Measures the median time between pushing a first commit (previous stage) and creating a merge request (MR) related to that commit. The key to keep the process tracked is to include the [issue closing pattern] to the description of the merge request (for example, `Closes #xxx`, where `xxx` is the number of the issue related to this merge request). If the issue closing pattern is not present in the merge request description, the MR is not considered to the measurement time of the stage. |
-| Test | Measures the median time to run the entire pipeline for that project. It's related to the time GitLab CI takes to run every job for the commits pushed to that merge request defined in the previous stage. It is basically the start->finish time for all pipelines. `master` is not excluded. It does not attempt to track time for any particular stages. |
-| Review | Measures the median time taken to review the merge request, between its creation and until it's merged. |
-| Staging | Measures the median time between merging the merge request until the very first deployment to production. It's tracked by the [environment] set to `production` or matching `production/*` (case-sensitive, `Production` won't work) in your GitLab CI configuration. If there isn't a production environment, this is not tracked. |
+| Test | Measures the median time to run the entire pipeline for that project. It's related to the time GitLab CI takes to run every job for the commits pushed to that merge request defined in the previous stage. It is basically the start->finish time for all pipelines. |
+| Review | Measures the median time taken to review the merge request that has closing issue pattern, between its creation and until it's merged. |
+| Staging | Measures the median time between merging the merge request with closing issue pattern until the very first deployment to production. It's tracked by the [environment] set to `production` or matching `production/*` (case-sensitive, `Production` won't work) in your GitLab CI configuration. If there isn't a production environment, this is not tracked. |
| Production| The sum of all time (medians) taken to run the entire process, from issue creation to deploying the code to production. |
---
@@ -77,8 +74,7 @@ To sum up, anything that doesn't follow the [GitLab flow] won't be tracked at al
So, the Cycle Analytics dashboard won't present any data:
- For merge requests that do not close an issue.
-- For issues not labeled with a label present in the Issue Board.
-- For issues not assigned a milestone.
+- For issues not labeled with a label present in the Issue Board or for issues not assigned a milestone.
- For staging and production stages, if the project has no `production` or `production/*`
environment.
@@ -86,7 +82,7 @@ So, the Cycle Analytics dashboard won't present any data:
Below is a simple fictional workflow of a single cycle that happens in a
single day passing through all seven stages. Note that if a stage does not have
-a start/stop mark, it is not measured and hence not calculated in the median
+a start and a stop mark, it is not measured and hence not calculated in the median
time. It is assumed that milestones are created and CI for testing and setting
environments is configured.
diff --git a/doc/user/project/import/github.md b/doc/user/project/import/github.md
index 8fba892594b..e194d57e2e0 100644
--- a/doc/user/project/import/github.md
+++ b/doc/user/project/import/github.md
@@ -60,6 +60,8 @@ For additional technical details, you can refer to the
[GitHub Importer](../../../development/github_importer.md "Working with the GitHub importer")
developer documentation.
+For an overview of the import process, see the video [Migrating from GitHub to GitLab](https://youtu.be/VYOXuOg9tQI).
+
## Import your GitHub repository into GitLab
### Using the GitHub integration
diff --git a/doc/user/project/index.md b/doc/user/project/index.md
index a24f525253d..587b4121e4e 100644
--- a/doc/user/project/index.md
+++ b/doc/user/project/index.md
@@ -84,6 +84,7 @@ When you create a project in GitLab, you'll have access to a large number of
- [Wiki](wiki/index.md): document your GitLab project in an integrated Wiki.
- [Snippets](../snippets.md): store, share and collaborate on code snippets.
- [Cycle Analytics](cycle_analytics.md): review your development lifecycle.
+- [Insights](insights/index.md): configure the Insights that matter for your projects. **[ULTIMATE]**
- [Security Dashboard](security_dashboard.md): Security Dashboard. **[ULTIMATE]**
- [Syntax highlighting](highlighting.md): an alternative to customize
your code blocks, overriding GitLab's default choice of language.
diff --git a/doc/user/project/insights/index.md b/doc/user/project/insights/index.md
index 3344e560870..2e2a27f112e 100644
--- a/doc/user/project/insights/index.md
+++ b/doc/user/project/insights/index.md
@@ -1,11 +1,7 @@
# Insights **[ULTIMATE]**
> Introduced in [GitLab Ultimate](https://about.gitlab.com/pricing/) 11.9 behind the `insights` feature flag.
-
-CAUTION: **Beta:**
-Insights is considered beta, and is not ready for production use.
-Follow [gitlab-org/quality/team-tasks#137](https://gitlab.com/gitlab-org/quality/team-tasks/issues/137#general-availability)
-for updates.
+> **Generally Available** (GA) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 12.0.
Configure the Insights that matter for your projects to explore data such as
triage hygiene, issues created/closed per a given period, average time for merge
diff --git a/doc/user/project/integrations/jira.md b/doc/user/project/integrations/jira.md
index c652149052e..234e3ad31cc 100644
--- a/doc/user/project/integrations/jira.md
+++ b/doc/user/project/integrations/jira.md
@@ -8,6 +8,8 @@ While you can always migrate content and process from Jira to GitLab Issues,
you can also opt to continue using Jira and use it together with GitLab through
our integration.
+For a video demonstration of integration with Jira, watch [GitLab workflow with Jira issues and Jenkins pipelines](https://youtu.be/Jn-_fyra7xQ).
+
Once you integrate your GitLab project with your Jira instance, you can automatically
detect and cross-reference activity between the GitLab project and any of your projects
in Jira. This includes the ability to close or transition Jira issues when the work
diff --git a/doc/user/project/integrations/webhooks.md b/doc/user/project/integrations/webhooks.md
index a0f500a939f..d5f28ddabc1 100644
--- a/doc/user/project/integrations/webhooks.md
+++ b/doc/user/project/integrations/webhooks.md
@@ -653,7 +653,33 @@ X-Gitlab-Event: Note Hook
"description": "test",
"milestone_id": null,
"state": "closed",
- "iid": 17
+ "iid": 17,
+ "labels": [
+ {
+ "id": 25,
+ "title": "Afterpod",
+ "color": "#3e8068",
+ "project_id": null,
+ "created_at": "2019-06-05T14:32:20.211Z",
+ "updated_at": "2019-06-05T14:32:20.211Z",
+ "template": false,
+ "description": null,
+ "type": "GroupLabel",
+ "group_id": 4
+ },
+ {
+ "id": 86,
+ "title": "Element",
+ "color": "#231afe",
+ "project_id": 4,
+ "created_at": "2019-06-05T14:32:20.637Z",
+ "updated_at": "2019-06-05T14:32:20.637Z",
+ "template": false,
+ "description": null,
+ "type": "ProjectLabel",
+ "group_id": null
+ }
+ ],
}
}
```
diff --git a/doc/user/project/issues/img/comment-or-discussion.png b/doc/user/project/issues/img/comment-or-discussion.png
new file mode 100644
index 00000000000..ccecc9fa39f
--- /dev/null
+++ b/doc/user/project/issues/img/comment-or-discussion.png
Binary files differ
diff --git a/doc/user/project/issues/img/create_mr_from_issue.png b/doc/user/project/issues/img/create_mr_from_issue.png
new file mode 100644
index 00000000000..680c42b5df0
--- /dev/null
+++ b/doc/user/project/issues/img/create_mr_from_issue.png
Binary files differ
diff --git a/doc/user/project/issues/img/issues_main_view_numbered.jpg b/doc/user/project/issues/img/issues_main_view_numbered.jpg
deleted file mode 100644
index b4b68476d24..00000000000
--- a/doc/user/project/issues/img/issues_main_view_numbered.jpg
+++ /dev/null
Binary files differ
diff --git a/doc/user/project/issues/img/issues_main_view_numbered.png b/doc/user/project/issues/img/issues_main_view_numbered.png
new file mode 100644
index 00000000000..16cb6b497b0
--- /dev/null
+++ b/doc/user/project/issues/img/issues_main_view_numbered.png
Binary files differ
diff --git a/doc/user/project/issues/img/reopen-issue.png b/doc/user/project/issues/img/reopen-issue.png
new file mode 100644
index 00000000000..1749be31239
--- /dev/null
+++ b/doc/user/project/issues/img/reopen-issue.png
Binary files differ
diff --git a/doc/user/project/issues/img/report-abuse.png b/doc/user/project/issues/img/report-abuse.png
new file mode 100644
index 00000000000..f189cbf1d36
--- /dev/null
+++ b/doc/user/project/issues/img/report-abuse.png
Binary files differ
diff --git a/doc/user/project/issues/img/show-all-activity.png b/doc/user/project/issues/img/show-all-activity.png
new file mode 100644
index 00000000000..c43ba75ce25
--- /dev/null
+++ b/doc/user/project/issues/img/show-all-activity.png
Binary files differ
diff --git a/doc/user/project/issues/index.md b/doc/user/project/issues/index.md
index 94865ad46ee..76dc6e49bce 100644
--- a/doc/user/project/issues/index.md
+++ b/doc/user/project/issues/index.md
@@ -86,7 +86,9 @@ For more information, see the [Issue Data and Actions](issue_data_and_actions.md
On the Issues List, you can view all issues in the current project, or from multiple projects when opening the Issues List from the higher-level group context. Filter the issue list by [any search query](../../search/index.md#issues-and-merge-requests-per-project) and/or specific metadata, such as label(s), assignees(s), status, and more. From this view, you can also make certain changes [in bulk](../bulk_editing.md) to the displayed issues.
-For more information, see the [Issue Data and Actions](issue_data_and_actions.md) page.
+For more information on interacting with Issues, see the [Issue Data and Actions](issue_data_and_actions.md) page.
+
+For sorting by issue priority, see [Label Priority](../labels.md#label-priority).
### Issue boards
@@ -123,7 +125,7 @@ For more information, see [Crosslinking issues](crosslinking_issues.md).
- [Close an issue](closing_issues.md)
- [Move an issue](moving_issues.md)
- [Delete an issue](deleting_issues.md)
-- [Create a merge request from an issue](issue_data_and_actions.md#18-new-merge-request)
+- [Create a merge request from an issue](issue_data_and_actions.md#22-create-merge-request)
## Advanced issue management
diff --git a/doc/user/project/issues/issue_data_and_actions.md b/doc/user/project/issues/issue_data_and_actions.md
index fc11c0251e0..da585022263 100644
--- a/doc/user/project/issues/issue_data_and_actions.md
+++ b/doc/user/project/issues/issue_data_and_actions.md
@@ -4,11 +4,13 @@ Please read through the [GitLab Issue Documentation](index.md) for an overview o
## Parts of an Issue
-The image below illustrates what an issue looks like:
+The image below illustrates what an issue may look like. Note that certain parts will
+look slightly different or will be absent, depending on the version of GitLab being used
+and the permissions of the user viewing the issue.
-![Issue view](img/issues_main_view_numbered.jpg)
+![Issue view](img/issues_main_view_numbered.png)
-You can find all the information on that issue on one screen.
+You can find all the information for that issue on one screen.
### Issue screen
@@ -16,157 +18,215 @@ An issue starts with its status (open or closed), followed by its author,
and includes many other functionalities, numbered in the image above to
explain what they mean, one by one.
-Many of the elements of the issue screen refresh automatically, such as the title and description, when they are changed by another user.
-Comments and system notes also appear automatically in response to various actions and content updates.
+Many of the elements of the issue screen refresh automatically, such as the title and
+description, when they are changed by another user. Comments and system notes also
+update automatically in response to various actions and content updates.
-#### 1. New Issue, close issue, edit
+#### 1. New Issue, close issue (reopen issue, report issue)
-- New issue: create a new issue in the same project
-- Close issue: close this issue
-- Edit: edit the same fields available when you create an issue.
+Clicking on **New issue** will open a new window to create a new issue in the same project.
+Clicking on **Close issue** will close this issue, but it will not be deleted. If the
+issue is already closed, you can still access it and the button will show **Reopen issue**, as shown below,
+which you can click to reopen the issue. A reopened issue is no different from any
+other issue.
+
+![Reopen Issue](img/reopen-issue.png)
+
+If you do not have rights to modify the issue, the **close issue** button will be
+replaced with **report issue**, which you can click to [submit an abuse report](../../abuse_reports.md)
+about the issue. It will also appear if you have rights to modify the issue, but only
+after it is closed.
+
+![Report Abuse](img/report-abuse.png)
#### 2. Todos
-- Add todo: add that issue to your [GitLab Todo](../../../workflow/todos.md) list
-- Mark todo as done: mark that issue as done (reflects on the Todo list)
+You can click **add todo** to add the issue to your [GitLab Todo](../../../workflow/todos.md)
+list. If it is already on your todo list, the buttom will show **mark todo as done**,
+which you can click to mark that issue as done (which will be reflected in the Todo list).
#### 3. Assignee
-Whenever someone starts to work on an issue, it can be assigned
-to that person. The assignee can be changed as much as needed.
-The idea is that the assignee is responsible for that issue until
-it's reassigned to someone else to take it from there.
+An issue can be assigned to yourself, another person, or [many people](#31-multiple-assignees-STARTER).
+The assignee(s) can be changed as much as needed. The idea is that the assignees are
+responsible for that issue until it's reassigned to someone else to take it from there.
+When assigned to someone, it will appear in their assigned issues list.
-> **Tip:**
-if a user is not member of that project, it can only be
+TIP: **Tip:**
+If a user is not member of that project, it can only be
assigned to them if they created the issue themselves.
##### 3.1. Multiple Assignees **[STARTER]**
-Often multiple people work on the same issue together,
-which can be especially difficult to track in large teams
-where there is shared ownership of an issue.
+Often multiple people work on the same issue together, which can be especially difficult
+to track in large teams where there is shared ownership of an issue.
In [GitLab Starter](https://about.gitlab.com/pricing/), you can
-assign multiple people to an issue.
+[assign multiple people](multiple_assignees_for_issues.md) to an issue.
+
+#### 4. Epic **[ULTIMATE]**
+
+You can assign issues to an [Epic](../../group/epics/index.md), which allows better
+management of groups of related issues.
-Learn more in the [Multiple Assignees documentation](multiple_assignees_for_issues.md).
+#### 5. Milestone
-#### 4. Milestone
+Select a [milestone](../milestones/index.md) to attribute that issue to.
-- Select a [milestone](../milestones/index.md) to attribute that issue to.
+#### 6. Time Tracking
-#### 5. Time Tracking
+Use [GitLab Quick Actions](../quick_actions.md) to [track estimates and time spent on issues](../../../workflow/time_tracking.md).
+You can add an [estimate of the time it will take](../../../workflow/time_tracking.md#estimates)
+to resolve the issue, and also add [the time spent](../../../workflow/time_tracking.md#time-spent)
+on the resolution of the issue.
-- Estimate time: add an estimate of the time it will take to resolve the issue.
-- Spend: add the time spent on the resolution of the issue
+#### 7. Due date
-> **Note:**
-Both estimate and spend times are set via [GitLab Quick Actions](../quick_actions.md).
+When you work on a tight schedule, it's important to have a way to set a deadline for
+implementations and for solving problems. This can be done in the [due date](due_dates.md)
+element. Due dates can be changed as many times as needed.
-Learn more in the [Time Tracking documentation](../../../workflow/time_tracking.md).
+#### 8. Labels
-#### 6. Due date
+Categorize issues by giving them [labels](../labels.md). They help to organize workflows,
+and they enable you to work with the [GitLab Issue Board](index.md#issue-boards).
-When you work on a tight schedule, it's important to
-have a way to set a deadline for implementations and for solving
-problems. This can be done in the [due date](due_dates.md) element. Due dates
-can be changed as many times as needed.
+Group Labels, which allow you to use the same labels for all projects within the same
+group, can be also given to issues. They work exactly the same, but they are immediately
+available to all projects in the group.
-#### 7. Labels
+TIP: **Tip:**
+If a label doesn't exist yet, you can click **Edit**, and it opens a dropdown menu
+from which you can select **Create new label**.
-Categorize issues by giving them [labels](../labels.md). They help to
-organize workflows, and they enable you to work with the
-[GitLab Issue Board](index.md#issue-boards).
+#### 9. Weight **[STARTER]**
-Group Labels, which allow you to use the same labels for a
-group of projects, can be also given to issues. They work exactly the same,
-but they are immediately available to all projects in the group.
+[Assign a weight](../../../workflow/issue_weight.md) to an issue.
+Larger values are used to indicate more effort is required to complete the issue. Only
+positive values or zero are allowed.
-> **Tip:**
-If a label doesn't exist yet, you can click **Edit**, and it opens a dropdown menu from which you can select **Create new label**.
+#### 10. Confidentiality
-#### 8. Weight **[STARTER]**
+You can [set an issue to be confidential](confidential_issues.md). When set, unauthorized
+users will not be able to access the issue, and will not see it listed in project
+issue boards or the issue list.
-- Assign a weight. Larger values are used to indicate more effort is required to complete the issue. Only positive values or zero are allowed.
+#### 11. Lock issue
-Learn more in the [Issue Weight documentation](../../../workflow/issue_weight.md).
+You can [lock the discussions](../../discussions/index.md#lock-discussions) in the issue,
+to prevent further comments from being added.
-#### 9. Participants
+#### 12. Participants
-- People involved in that issue (mentioned in the description or in the [discussion](../../discussions/index.md)).
+All the users involved in that issue. Either they participated in the [discussion](../../discussions/index.md),
+or were mentioned in the description or discussions.
-#### 10. Notifications
+#### 13. Notifications
-- Subscribe: if you are not a participant of the discussion on that issue, but
- want to receive notifications on each new input, subscribe to it.
-- Unsubscribe: if you are receiving notifications on that issue but no
+Click on the icon to enable/disable [notifications](../../../workflow/notifications.md#issue--epics--merge-request-events)
+for the issue. This will automatically enable if you participate in the issue in any way.
+
+- **Enable**: If you are not a participant in the discussion on that issue, but
+ want to receive notifications on each update, subscribe to it.
+- **Disable**: If you are receiving notifications for updates to that issue but no
longer want to receive them, unsubscribe from it.
-Read more in the [notifications documentation](../../../workflow/notifications.md#issue--epics--merge-request-events).
+#### 14. Reference
+
+- A quick "copy to clipboard" button for that issue's reference, which looks like `foo/bar#xxx`,
+ where `foo` is the `username` or `groupname`, `bar` is the `project-name`, and
+ `xxx` is the issue number.
+
+#### 15. Edit
+
+Clicking this icon opens the issue for editing, and you will have access to all the
+same fields as when the issue was created. This icon will not display if the user
+does not have permission to edit the issue.
+
+#### 16. Description
+
+The plain text title and description of the issue fill the top center of the issue page.
+The description fully supports [GitLab Flavored Markdown](../../markdown.md#gitlab-flavored-markdown-gfm),
+allowing many formatting options.
+
+#### 17. Mentions
+
+You can mention a user or a group present in your GitLab instance with `@username` or
+`@groupname` and they will be notified via todos and email, unless they have disabled
+all notifications in their profile settings. This is controlled in the
+[notification settings](../../../workflow/notifications.md).
+
+Mentions for yourself (the current logged in user), will be highlighted in a different
+color, allowing you to easily see which comments involve you, helping you focus on
+them quickly.
+
+TIP: **Tip:**
+Avoid mentioning `@all` in issues and merge requests, as it sends an email notification
+to all the members of that project's group, which can be interpreted as spam.
+
+#### 18. Related Issues **[STARTER]**
+
+Issues that were mentioned as [related issues](related_issues.md) are listed here.
+You can also click the `+` to add more related issues.
+
+#### 19. Related Merge Requests
-#### 11. Reference
+Merge requests that were mentioned in that issue's description or in the issue discussion
+thread are listed as [related merge requests](crosslinking_issues.md#from-merge-requests) here.
+Also, if the current issue was mentioned as related in another merge request, that
+merge request will be listed here.
-- A quick "copy to clipboard" button for that issue's reference, `foo/bar#xxx`, where `foo` is the `username` or `groupname`, `bar`
- is the `project-name`, and `xxx` is the issue number.
+#### 20. Award emoji
-#### 12. Title and description
+You can award an emoji to that issue. There are shortcuts to "thumbs_up" and "thumbs_down",
+or you can click on the light gray "face" to choose a different reaction from the
+dropdown list of available [GitLab Flavored Markdown Emoji](../../markdown.md#emoji).
-- Title: a plain text title for describing the subject of the issue.
-- Description: a large text field which fully supports [GitLab Flavored Markdown](../../markdown.md#gitlab-flavored-markdown-gfm),
- to describe all the details of the issue.
+TIP: **Tip:**
+Posting "+1" as a comment in a thread spams all subscribed participants of that issue,
+clutters the discussion threads, and is not recommended. Awarding an emoji is a way
+to let them know your reaction without spamming them.
-#### 13. Mentions
+#### 21. Show all activity
-- You can mention a user or a group present in your GitLab instance with
- `@username` or `@groupname` and they will be notified via todos and email, unless
- they have disabled all notifications in their profile settings.
-- Mentions for yourself (the current logged in user), will be highlighted
- in a different color, allowing you to easily see which comments involve you,
- helping you focus on them quickly.
+You can filter what is displayed in the issue history by clicking on **Show all activity**
+and selecting either **Show comments only**, which only shows discussions and hides
+updates to the issue, or **Show history only**, which hides discussions and only shows updates.
-To change your [notification settings](../../../workflow/notifications.md), navigate to
-**Profile Settings** > **Notifications** > **Global notification level**
-and choose your preference from the dropdown menu.
+![Show all activity](img/show-all-activity.png)
-> **Tip:**
-Avoid mentioning `@all` in issues and merge requests,
-as it sends an email notification
-to all the members of that project's group, which can be
-interpreted as spam.
+#### 22. Create Merge Request
-#### 14. Related Merge Requests
+Create a new branch and [WIP merge request](../merge_requests/work_in_progress_merge_requests.md)
+in one action. The branch will be named `issuenumber-title` by default, but you can
+choose any name, and GitLab will verify that it is not already in use. The merge request
+will automatically inherit the milestone and labels of the issue, and will be set to
+close the issue when it is merged.
-- Any merge requests mentioned in that issue's description
- or in the issue discussion thread.
+![Create MR from issue](img/create_mr_from_issue.png)
-#### 15. Award emoji
+Optionally, you can choose to create a [new branch](../repository/web_editor.md#create-a-new-branch-from-an-issue)
+only, named after that issue.
-- Award an emoji to that issue.
+#### 23. Issue history
-> **Tip:**
-Posting "+1" as a comment in a thread spams all subscribed
-participants of that issue. Awarding an emoji is a way to let them
-know you like it without spamming them.
+All comments and updates to the issue are tracked and listed here, but this can be
+filtered, as shown above.
-#### 16. Thread
+#### 24. Comments
-- Comments: collaborate to that issue by posting comments in its thread.
- These text fields also fully support
- [GitLab Flavored Markdown](../../markdown.md#gitlab-flavored-markdown-gfm).
+Collaborate in the issue by posting comments in its thread. This text field also fully
+supports [GitLab Flavored Markdown](../../markdown.md#gitlab-flavored-markdown-gfm).
-#### 17. Comment, start a discussion, or comment and close
+#### 25. Submit Comment, start a discussion, or comment and close
-Once you write a comment, you can either:
+Once you write a comment, you can:
-- Click "Comment" and your comment will be published.
-- Click "Start discussion": start a thread within that issue's thread to discuss specific points.
-- Click "Comment and close issue": post your comment and close that issue in one click.
+- Click **Comment** and your comment will be published.
+- Choose **Start discussion** from the dropdown list and start a new [discussion thread](../../discussions/index.md#threaded-discussions)
+ within that issue's main thread to discuss specific points. This invites other participants
+ to reply directly to your discussion, keeping related comments grouped together.
-#### 18. New Merge Request
+![Comment or discussion](img/comment-or-discussion.png)
-- Create a new merge request (with a new source branch named after the issue) in one action.
- The merge request will automatically inherit the milestone and labels of the issue. The merge
- request will automatically close that issue when it is merged.
-- Optionally, you can just create a [new branch](../repository/web_editor.md#create-a-new-branch-from-an-issue)
- named after that issue.
+You can also close the issue from here, so you don't need to scroll to the top of the issue page.
diff --git a/doc/user/project/issues/moving_issues.md b/doc/user/project/issues/moving_issues.md
index 211a651b89e..8aac2c01444 100644
--- a/doc/user/project/issues/moving_issues.md
+++ b/doc/user/project/issues/moving_issues.md
@@ -8,3 +8,28 @@ There will also be a system note added to both issues indicating where it came f
You can move an issue with the "Move issue" button at the bottom of the right-sidebar when viewing the issue.
![move issue - button](img/sidebar_move_issue.png)
+
+## Troubleshooting
+
+### Moving Issues in Bulk
+
+If you have advanced technical skills you can also bulk move all the issues from one project to another in the rails console. The below script will move all the issues from one project to another that are not in status **closed**.
+
+To access rails console run `sudo gitlab-rails console` on the GitLab server and run the below script. Please be sure to change **project**, **admin_user** and **target_project** to your values. We do also recommend [creating a backup](https://docs.gitlab.com/ee/raketasks/backup_restore.html#creating-a-backup-of-the-gitlab-system) before attempting any changes in the console.
+
+```ruby
+project = Project.find_by_full_path('full path of the project where issues are moved from')
+issues = project.issues
+admin_user = User.find_by_username('username of admin user') # make sure user has permissions to move the issues
+target_project = Project.find_by_full_path('full path of target project where issues moved to')
+
+issues.each do |issue|
+ if issue.state != "closed" && issue.moved_to.nil?
+ Issues::MoveService.new(project, admin_user).execute(issue, target_project)
+ else
+ puts "issue with id: #{issue.id} and title: #{issue.title} was not moved"
+ end
+end; nil
+
+```
+
diff --git a/doc/user/project/operations/img/external_dashboard_link.png b/doc/user/project/operations/img/external_dashboard_link.png
new file mode 100644
index 00000000000..4fb8bce7cd0
--- /dev/null
+++ b/doc/user/project/operations/img/external_dashboard_link.png
Binary files differ
diff --git a/doc/user/project/operations/img/external_dashboard_settings.png b/doc/user/project/operations/img/external_dashboard_settings.png
new file mode 100644
index 00000000000..8dc380f01e2
--- /dev/null
+++ b/doc/user/project/operations/img/external_dashboard_settings.png
Binary files differ
diff --git a/doc/user/project/operations/index.md b/doc/user/project/operations/index.md
index 0086c15c98a..84711d1146f 100644
--- a/doc/user/project/operations/index.md
+++ b/doc/user/project/operations/index.md
@@ -9,3 +9,4 @@ your applications:
- Discover and view errors generated by your applications with [Error Tracking](error_tracking.md).
- Create, toggle, and remove [Feature Flags](feature_flags.md). **[PREMIUM]**
- [Trace](tracing.md) the performance and health of a deployed application. **[ULTIMATE]**
+- Add a [button to the Monitoring dashboard](linking_to_an_external_dashboard.md) linking directly to your existing external dashboards.
diff --git a/doc/user/project/operations/linking_to_an_external_dashboard.md b/doc/user/project/operations/linking_to_an_external_dashboard.md
new file mode 100644
index 00000000000..0371a40a217
--- /dev/null
+++ b/doc/user/project/operations/linking_to_an_external_dashboard.md
@@ -0,0 +1,19 @@
+# Linking to an external dashboard
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-ce/issues/57171) in GitLab 12.0.
+
+You can add a button to the Monitoring dashboard linking directly to your existing external dashboards.
+
+## Enabling the external dashboard link
+
+1. Go to **Settings > Operations** and scroll to the section titled **External dashboard**.
+
+1. Fill in the URL to your external dashboard and click **Save changes**.
+
+ ![External Dashboard Settings](img/external_dashboard_settings.png)
+
+1. There should now be a button on your
+ [Monitoring dashboard](../../../ci/environments.md#monitoring-environments) which
+ will open the URL you entered in the above step.
+
+ ![External Dashboard Link](img/external_dashboard_link.png)
diff --git a/doc/user/project/settings/index.md b/doc/user/project/settings/index.md
index e3502a632d9..ba890c5ac01 100644
--- a/doc/user/project/settings/index.md
+++ b/doc/user/project/settings/index.md
@@ -26,6 +26,12 @@ Set up your project's access, [visibility](../../../public_access/public_access.
![projects sharing permissions](img/sharing_and_permissions_settings.png)
+If Issues are disabled, or you can't access Issues because you're not a project member, then Lables and Milestones
+links will be missing from the sidebar UI.
+
+You can still access them with direct links if you can access Merge Requests. This is deliberate, if you can see
+Issues or Merge Requests, both of which use Labels and Milestones, then you shouldn't be denied access to Labels and Milestones pages.
+
### Issue settings
Add an [issue description template](../description_templates.md#description-templates) to your project, so that every new issue will start with a custom template.
diff --git a/doc/workflow/gitlab_flow.md b/doc/workflow/gitlab_flow.md
index 7d0abb93262..3e24557591c 100644
--- a/doc/workflow/gitlab_flow.md
+++ b/doc/workflow/gitlab_flow.md
@@ -27,6 +27,8 @@ People have a hard time figuring out which branch has the latest code, or which
Frequently, the reaction to this problem is to adopt a standardized pattern such as [Git flow](https://nvie.com/posts/a-successful-git-branching-model/) and [GitHub flow](http://scottchacon.com/2011/08/31/github-flow.html).
We think there is still room for improvement. In this document, we describe a set of practices we call GitLab flow.
+For a video introduction of how this works in GitLab, see [GitLab Flow](https://youtu.be/InKNIvky2KE).
+
## Git flow and its problems
![Git Flow timeline by Vincent Driessen, used with permission](gitdashflow.png)
diff --git a/lib/api/entities.rb b/lib/api/entities.rb
index f8b950cb55d..8840accf675 100644
--- a/lib/api/entities.rb
+++ b/lib/api/entities.rb
@@ -265,6 +265,7 @@ module API
expose :open_issues_count, if: lambda { |project, options| project.feature_available?(:issues, options[:current_user]) }
expose :runners_token, if: lambda { |_project, options| options[:user_can_admin_project] }
+ expose :ci_default_git_depth
expose :public_builds, as: :public_jobs
expose :ci_config_path, if: -> (project, options) { Ability.allowed?(options[:current_user], :download_code, project) }
expose :shared_with_groups do |project, options|
@@ -287,6 +288,7 @@ module API
# N+1 is solved then by using `subject.tags.map(&:name)`
# MR describing the solution: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/20555
super(projects_relation).preload(:group)
+ .preload(:ci_cd_settings)
.preload(project_group_links: { group: :route },
fork_network: :root_project,
fork_network_member: :forked_from_project,
@@ -701,7 +703,7 @@ module API
# See https://gitlab.com/gitlab-org/gitlab-ce/issues/42344 for more
# information.
expose :merge_status do |merge_request|
- merge_request.check_mergeability
+ merge_request.check_if_can_be_merged
merge_request.merge_status
end
expose :diff_head_sha, as: :sha
diff --git a/lib/api/helpers/projects_helpers.rb b/lib/api/helpers/projects_helpers.rb
index 813e46e9520..f242f1fea0e 100644
--- a/lib/api/helpers/projects_helpers.rb
+++ b/lib/api/helpers/projects_helpers.rb
@@ -29,6 +29,7 @@ module API
optional :merge_method, type: String, values: %w(ff rebase_merge merge), desc: 'The merge method used when merging merge requests'
optional :initialize_with_readme, type: Boolean, desc: "Initialize a project with a README.md"
optional :external_authorization_classification_label, type: String, desc: 'The classification label for the project'
+ optional :ci_default_git_depth, type: Integer, desc: 'Default number of revisions for shallow cloning'
end
params :optional_project_params_ee do
diff --git a/lib/api/issues.rb b/lib/api/issues.rb
index 56960a2eb64..039ebf92187 100644
--- a/lib/api/issues.rb
+++ b/lib/api/issues.rb
@@ -252,14 +252,9 @@ module API
issue = user_project.issues.find_by!(iid: params.delete(:issue_iid))
authorize! :update_issue, issue
- # Setting updated_at only allowed for admins and owners as well
- if params[:updated_at].present?
- if current_user.admin? || user_project.owner == current_user || current_user.owned_groups.include?(user_project.owner)
- issue.system_note_timestamp = params[:updated_at]
- else
- params.delete(:updated_at)
- end
- end
+ # Setting updated_at is allowed only for admins and owners
+ params.delete(:updated_at) unless current_user.can?(:set_issue_updated_at, user_project)
+ issue.system_note_timestamp = params[:updated_at]
update_params = declared_params(include_missing: false).merge(request: request, api: true)
diff --git a/lib/api/merge_requests.rb b/lib/api/merge_requests.rb
index 5bbf6df78b0..955624404f1 100644
--- a/lib/api/merge_requests.rb
+++ b/lib/api/merge_requests.rb
@@ -397,16 +397,28 @@ module API
present merge_request, with: Entities::MergeRequest, current_user: current_user, project: user_project
end
- desc 'Returns the up to date merge-ref HEAD commit'
- get ':id/merge_requests/:merge_request_iid/merge_ref' do
+ desc 'Merge a merge request to its default temporary merge ref path'
+ params do
+ optional :merge_commit_message, type: String, desc: 'Custom merge commit message'
+ end
+ put ':id/merge_requests/:merge_request_iid/merge_to_ref' do
merge_request = find_project_merge_request(params[:merge_request_iid])
- result = ::MergeRequests::MergeabilityCheckService.new(merge_request).execute
+ authorize! :admin_merge_request, user_project
+
+ merge_params = {
+ commit_message: params[:merge_commit_message]
+ }
+
+ result = ::MergeRequests::MergeToRefService
+ .new(merge_request.target_project, current_user, merge_params)
+ .execute(merge_request)
- if result.success?
- present :commit_id, result.payload.dig(:merge_ref_head, :commit_id)
+ if result[:status] == :success
+ present result.slice(:commit_id), 200
else
- render_api_error!(result.message, 400)
+ http_status = result[:http_status] || 400
+ render_api_error!(result[:message], http_status)
end
end
diff --git a/lib/banzai/pipeline/gfm_pipeline.rb b/lib/banzai/pipeline/gfm_pipeline.rb
index 30cafd11834..d67f461be57 100644
--- a/lib/banzai/pipeline/gfm_pipeline.rb
+++ b/lib/banzai/pipeline/gfm_pipeline.rb
@@ -25,7 +25,6 @@ module Banzai
Filter::VideoLinkFilter,
Filter::ImageLazyLoadFilter,
Filter::ImageLinkFilter,
- Filter::EmojiFilter,
Filter::TableOfContentsFilter,
Filter::AutolinkFilter,
Filter::ExternalLinkFilter,
@@ -34,6 +33,7 @@ module Banzai
*reference_filters,
+ Filter::EmojiFilter,
Filter::TaskListFilter,
Filter::InlineDiffFilter,
diff --git a/lib/gitlab/ci/templates/Serverless.gitlab-ci.yml b/lib/gitlab/ci/templates/Serverless.gitlab-ci.yml
index 3f46bb89e94..a3db2705bf6 100644
--- a/lib/gitlab/ci/templates/Serverless.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Serverless.gitlab-ci.yml
@@ -14,7 +14,7 @@ stages:
.serverless:deploy:image:
stage: deploy
- image: gcr.io/triggermesh/tm@sha256:3cfdd470a66b741004fb02354319d79f1598c70117ce79978d2e07e192bfb336 # v0.0.11
+ image: gcr.io/triggermesh/tm@sha256:3cfdd470a66b741004fb02354319d79f1598c70117ce79978d2e07e192bfb336 # v0.0.11
environment: development
script:
- echo "$CI_REGISTRY_IMAGE"
diff --git a/lib/gitlab/cluster/puma_worker_killer_initializer.rb b/lib/gitlab/cluster/puma_worker_killer_initializer.rb
index 4ed9a9a02ab..4affc52b7b0 100644
--- a/lib/gitlab/cluster/puma_worker_killer_initializer.rb
+++ b/lib/gitlab/cluster/puma_worker_killer_initializer.rb
@@ -27,6 +27,9 @@ module Gitlab
# is restarted already, thus periodically restarting workers shouldn't be
# needed.
config.rolling_restart_frequency = false
+
+ observer = Gitlab::Cluster::PumaWorkerKillerObserver.new
+ config.pre_term = observer.callback
end
PumaWorkerKiller.start
diff --git a/lib/gitlab/cluster/puma_worker_killer_observer.rb b/lib/gitlab/cluster/puma_worker_killer_observer.rb
new file mode 100644
index 00000000000..3b4ebc3fbae
--- /dev/null
+++ b/lib/gitlab/cluster/puma_worker_killer_observer.rb
@@ -0,0 +1,24 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Cluster
+ class PumaWorkerKillerObserver
+ def initialize
+ @counter = Gitlab::Metrics.counter(:puma_killer_terminations_total, 'Number of workers terminated by PumaWorkerKiller')
+ end
+
+ # returns the Proc to be used as the observer callback block
+ def callback
+ method(:log_termination)
+ end
+
+ private
+
+ def log_termination(worker)
+ labels = { worker: "worker_#{worker.index}" }
+
+ @counter.increment(labels)
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/cluster/rack_timeout_observer.rb b/lib/gitlab/cluster/rack_timeout_observer.rb
new file mode 100644
index 00000000000..5182b2be148
--- /dev/null
+++ b/lib/gitlab/cluster/rack_timeout_observer.rb
@@ -0,0 +1,51 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Cluster
+ class RackTimeoutObserver
+ TRANSITION_STATES = %i(ready active).freeze
+
+ def initialize
+ @counter = Gitlab::Metrics.counter(:rack_requests_total, 'Number of requests in a given rack state')
+ end
+
+ # returns the Proc to be used as the observer callback block
+ def callback
+ method(:log_timeout_exception)
+ end
+
+ private
+
+ def log_timeout_exception(env)
+ info = env[::Rack::Timeout::ENV_INFO_KEY]
+ return unless info
+ return if TRANSITION_STATES.include?(info.state)
+
+ @counter.increment(labels(info, env))
+ end
+
+ def labels(info, env)
+ params = controller_params(env) || grape_params(env) || {}
+
+ {
+ controller: params['controller'],
+ action: params['action'],
+ route: params['route'],
+ state: info.state
+ }
+ end
+
+ def controller_params(env)
+ env['action_dispatch.request.parameters']
+ end
+
+ def grape_params(env)
+ endpoint = env[Grape::Env::API_ENDPOINT]
+ route = endpoint&.route&.pattern&.origin
+ return unless route
+
+ { 'route' => route }
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/data_builder/note.rb b/lib/gitlab/data_builder/note.rb
index 65601dcdf31..16e62622ed4 100644
--- a/lib/gitlab/data_builder/note.rb
+++ b/lib/gitlab/data_builder/note.rb
@@ -44,6 +44,7 @@ module Gitlab
data[:commit] = build_data_for_commit(project, user, note)
elsif note.for_issue?
data[:issue] = note.noteable.hook_attrs
+ data[:issue][:labels] = note.noteable.labels(&:hook_attrs)
elsif note.for_merge_request?
data[:merge_request] = note.noteable.hook_attrs
elsif note.for_snippet?
diff --git a/lib/gitlab/gitaly_client/conflicts_service.rb b/lib/gitlab/gitaly_client/conflicts_service.rb
index 077b63205a8..d16e45c964d 100644
--- a/lib/gitlab/gitaly_client/conflicts_service.rb
+++ b/lib/gitlab/gitaly_client/conflicts_service.rb
@@ -65,9 +65,9 @@ module Gitlab
our_commit_oid: @our_commit_oid,
target_repository: target_repository.gitaly_repository,
their_commit_oid: @their_commit_oid,
- source_branch: source_branch,
- target_branch: target_branch,
- commit_message: resolution.commit_message,
+ source_branch: encode_binary(source_branch),
+ target_branch: encode_binary(target_branch),
+ commit_message: encode_binary(resolution.commit_message),
user: Gitlab::Git::User.from_gitlab(resolution.user).to_gitaly
)
end
diff --git a/lib/gitlab/gitaly_client/operation_service.rb b/lib/gitlab/gitaly_client/operation_service.rb
index e4a59ee3f9b..b42e6cbad8d 100644
--- a/lib/gitlab/gitaly_client/operation_service.rb
+++ b/lib/gitlab/gitaly_client/operation_service.rb
@@ -107,7 +107,7 @@ module Gitlab
branch: encode_binary(branch),
target_ref: encode_binary(target_ref),
user: Gitlab::Git::User.from_gitlab(user).to_gitaly,
- message: message
+ message: encode_binary(message)
)
response = GitalyClient.call(@repository.storage, :operation_service, :user_merge_to_ref, request)
diff --git a/lib/gitlab/graphql/loaders/batch_lfs_oid_loader.rb b/lib/gitlab/graphql/loaders/batch_lfs_oid_loader.rb
new file mode 100644
index 00000000000..8f34e58a771
--- /dev/null
+++ b/lib/gitlab/graphql/loaders/batch_lfs_oid_loader.rb
@@ -0,0 +1,25 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Graphql
+ module Loaders
+ class BatchLfsOidLoader
+ def initialize(repository, blob_id)
+ @repository, @blob_id = repository, blob_id
+ end
+
+ def find
+ BatchLoader.for(blob_id).batch(key: repository) do |blob_ids, loader, batch_args|
+ Gitlab::Git::Blob.batch_lfs_pointers(batch_args[:key], blob_ids).each do |loaded_blob|
+ loader.call(loaded_blob.id, loaded_blob.lfs_oid)
+ end
+ end
+ end
+
+ private
+
+ attr_reader :repository, :blob_id
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/hook_data/issue_builder.rb b/lib/gitlab/hook_data/issue_builder.rb
index d39ff8c21cc..cfc9ebe4f92 100644
--- a/lib/gitlab/hook_data/issue_builder.rb
+++ b/lib/gitlab/hook_data/issue_builder.rb
@@ -44,7 +44,8 @@ module Gitlab
human_total_time_spent: issue.human_total_time_spent,
human_time_estimate: issue.human_time_estimate,
assignee_ids: issue.assignee_ids,
- assignee_id: issue.assignee_ids.first # This key is deprecated
+ assignee_id: issue.assignee_ids.first, # This key is deprecated
+ labels: issue.labels
}
issue.attributes.with_indifferent_access.slice(*self.class.safe_hook_attributes)
diff --git a/lib/gitlab/import_export/import_export.yml b/lib/gitlab/import_export/import_export.yml
index 7bbcb53f016..71c44af9254 100644
--- a/lib/gitlab/import_export/import_export.yml
+++ b/lib/gitlab/import_export/import_export.yml
@@ -156,6 +156,9 @@ excluded_attributes:
- :when
- :artifacts_file
- :artifacts_metadata
+ - :artifacts_file_store
+ - :artifacts_metadata_store
+ - :artifacts_size
- :commands
push_event_payload:
- :event_id
diff --git a/lib/gitlab/import_export/relation_factory.rb b/lib/gitlab/import_export/relation_factory.rb
index e1e70a008d9..efd3f550a22 100644
--- a/lib/gitlab/import_export/relation_factory.rb
+++ b/lib/gitlab/import_export/relation_factory.rb
@@ -153,6 +153,9 @@ module Gitlab
@relation_hash.delete('trace') # old export files have trace
@relation_hash.delete('token')
@relation_hash.delete('commands')
+ @relation_hash.delete('artifacts_file_store')
+ @relation_hash.delete('artifacts_metadata_store')
+ @relation_hash.delete('artifacts_size')
imported_object
elsif @relation_name == :merge_requests
diff --git a/lib/gitlab/metrics/dashboard/base_service.rb b/lib/gitlab/metrics/dashboard/base_service.rb
index 94aabd0466c..4664aee71f6 100644
--- a/lib/gitlab/metrics/dashboard/base_service.rb
+++ b/lib/gitlab/metrics/dashboard/base_service.rb
@@ -6,13 +6,13 @@ module Gitlab
module Metrics
module Dashboard
class BaseService < ::BaseService
- DASHBOARD_LAYOUT_ERROR = Gitlab::Metrics::Dashboard::Stages::BaseStage::DashboardLayoutError
+ PROCESSING_ERROR = Gitlab::Metrics::Dashboard::Stages::BaseStage::DashboardProcessingError
def get_dashboard
return error("#{dashboard_path} could not be found.", :not_found) unless path_available?
success(dashboard: process_dashboard)
- rescue DASHBOARD_LAYOUT_ERROR => e
+ rescue PROCESSING_ERROR => e
error(e.message, :unprocessable_entity)
end
diff --git a/lib/gitlab/metrics/dashboard/processor.rb b/lib/gitlab/metrics/dashboard/processor.rb
index dd986020693..a33a010ad97 100644
--- a/lib/gitlab/metrics/dashboard/processor.rb
+++ b/lib/gitlab/metrics/dashboard/processor.rb
@@ -11,11 +11,13 @@ module Gitlab
SYSTEM_SEQUENCE = [
Stages::CommonMetricsInserter,
Stages::ProjectMetricsInserter,
+ Stages::EndpointInserter,
Stages::Sorter
].freeze
PROJECT_SEQUENCE = [
Stages::CommonMetricsInserter,
+ Stages::EndpointInserter,
Stages::Sorter
].freeze
diff --git a/lib/gitlab/metrics/dashboard/stages/base_stage.rb b/lib/gitlab/metrics/dashboard/stages/base_stage.rb
index a6d1f974556..0db7b176e8d 100644
--- a/lib/gitlab/metrics/dashboard/stages/base_stage.rb
+++ b/lib/gitlab/metrics/dashboard/stages/base_stage.rb
@@ -5,7 +5,8 @@ module Gitlab
module Dashboard
module Stages
class BaseStage
- DashboardLayoutError = Class.new(StandardError)
+ DashboardProcessingError = Class.new(StandardError)
+ LayoutError = Class.new(DashboardProcessingError)
DEFAULT_PANEL_TYPE = 'area-chart'
@@ -25,15 +26,15 @@ module Gitlab
protected
def missing_panel_groups!
- raise DashboardLayoutError.new('Top-level key :panel_groups must be an array')
+ raise LayoutError.new('Top-level key :panel_groups must be an array')
end
def missing_panels!
- raise DashboardLayoutError.new('Each "panel_group" must define an array :panels')
+ raise LayoutError.new('Each "panel_group" must define an array :panels')
end
def missing_metrics!
- raise DashboardLayoutError.new('Each "panel" must define an array :metrics')
+ raise LayoutError.new('Each "panel" must define an array :metrics')
end
def for_metrics
diff --git a/lib/gitlab/metrics/dashboard/stages/endpoint_inserter.rb b/lib/gitlab/metrics/dashboard/stages/endpoint_inserter.rb
new file mode 100644
index 00000000000..2a959854be0
--- /dev/null
+++ b/lib/gitlab/metrics/dashboard/stages/endpoint_inserter.rb
@@ -0,0 +1,42 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Metrics
+ module Dashboard
+ module Stages
+ class EndpointInserter < BaseStage
+ MissingQueryError = Class.new(DashboardProcessingError)
+
+ def transform!
+ for_metrics do |metric|
+ metric[:prometheus_endpoint_path] = endpoint_for_metric(metric)
+ end
+ end
+
+ private
+
+ def endpoint_for_metric(metric)
+ Gitlab::Routing.url_helpers.prometheus_api_project_environment_path(
+ project,
+ environment,
+ proxy_path: query_type(metric),
+ query: query_for_metric(metric)
+ )
+ end
+
+ def query_type(metric)
+ metric[:query] ? :query : :query_range
+ end
+
+ def query_for_metric(metric)
+ query = metric[query_type(metric)]
+
+ raise MissingQueryError.new('Each "metric" must define one of :query or :query_range') unless query
+
+ query
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/omniauth_initializer.rb b/lib/gitlab/omniauth_initializer.rb
index 83204fa5d18..2a2083ebae0 100644
--- a/lib/gitlab/omniauth_initializer.rb
+++ b/lib/gitlab/omniauth_initializer.rb
@@ -63,12 +63,6 @@ module Gitlab
{ remote_sign_out_handler: authentiq_signout_handler }
when 'shibboleth'
{ fail_with_empty_uid: true }
- when 'openid_connect'
- # If a name argument is omitted, OmniAuth will expect that the
- # matching route is /auth/users/openidconnect instead of
- # /auth/users/openid_connect because of
- # https://gitlab.com/gitlab-org/gitlab-ce/issues/62208#note_178780341.
- { name: 'openid_connect' }
else
{}
end
diff --git a/lib/gitlab/performance_bar/peek_query_tracker.rb b/lib/gitlab/performance_bar/peek_query_tracker.rb
index 16c16aa0265..3a27e26eaba 100644
--- a/lib/gitlab/performance_bar/peek_query_tracker.rb
+++ b/lib/gitlab/performance_bar/peek_query_tracker.rb
@@ -27,15 +27,16 @@ module Gitlab
subscribe('sql.active_record') do |_, start, finish, _, data|
if Gitlab::SafeRequestStore.store[:peek_enabled]
unless data[:cached]
- track_query(data[:sql].strip, data[:binds], start, finish)
+ backtrace = Gitlab::Profiler.clean_backtrace(caller)
+ track_query(data[:sql].strip, data[:binds], backtrace, start, finish)
end
end
end
end
- def track_query(raw_query, bindings, start, finish)
+ def track_query(raw_query, bindings, backtrace, start, finish)
duration = (finish - start) * 1000.0
- query_info = { duration: duration.round(3), sql: raw_query }
+ query_info = { duration: duration.round(3), sql: raw_query, backtrace: backtrace }
PEEK_DB_CLIENT.query_details << query_info
end
diff --git a/lib/gitlab/rack_timeout_observer.rb b/lib/gitlab/rack_timeout_observer.rb
deleted file mode 100644
index 80d3f7dea60..00000000000
--- a/lib/gitlab/rack_timeout_observer.rb
+++ /dev/null
@@ -1,46 +0,0 @@
-# frozen_string_literal: true
-
-module Gitlab
- class RackTimeoutObserver
- def initialize
- @counter = Gitlab::Metrics.counter(:rack_state_total, 'Number of requests in a given rack state')
- end
-
- # returns the Proc to be used as the observer callback block
- def callback
- method(:log_timeout_exception)
- end
-
- private
-
- def log_timeout_exception(env)
- info = env[::Rack::Timeout::ENV_INFO_KEY]
- return unless info
-
- @counter.increment(labels(info, env))
- end
-
- def labels(info, env)
- params = controller_params(env) || grape_params(env) || {}
-
- {
- controller: params['controller'],
- action: params['action'],
- route: params['route'],
- state: info.state
- }
- end
-
- def controller_params(env)
- env['action_dispatch.request.parameters']
- end
-
- def grape_params(env)
- endpoint = env[Grape::Env::API_ENDPOINT]
- route = endpoint&.route&.pattern&.origin
- return unless route
-
- { 'route' => route }
- end
- end
-end
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index 2845daf51e3..88ace6057cf 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -565,6 +565,9 @@ msgstr ""
msgid "Add comment now"
msgstr ""
+msgid "Add email address"
+msgstr ""
+
msgid "Add header and footer to emails. Please note that color settings will only be applied within the application interface"
msgstr ""
@@ -775,6 +778,9 @@ msgstr ""
msgid "All changes are committed"
msgstr ""
+msgid "All email addresses will be used to identify your commits."
+msgstr ""
+
msgid "All features are enabled for blank projects, from templates, or when importing, but you can disable them afterward in the project settings."
msgstr ""
@@ -2798,6 +2804,9 @@ msgstr ""
msgid "Confirm"
msgstr ""
+msgid "Confirmation email sent to %{email}"
+msgstr ""
+
msgid "Confirmation required"
msgstr ""
@@ -2906,6 +2915,9 @@ msgstr ""
msgid "ContributorsPage|Please wait a moment, this page will automatically refresh when ready."
msgstr ""
+msgid "Control emails linked to your account"
+msgstr ""
+
msgid "Control the display of third party offers."
msgstr ""
@@ -3757,6 +3769,9 @@ msgstr ""
msgid "Enable Sentry for error reporting and logging."
msgstr ""
+msgid "Enable access to the Performance Bar for a given group."
+msgstr ""
+
msgid "Enable and configure InfluxDB metrics."
msgstr ""
@@ -3790,9 +3805,6 @@ msgstr ""
msgid "Enable shared Runners"
msgstr ""
-msgid "Enable the Performance Bar for a given group."
-msgstr ""
-
msgid "Enable two-factor authentication"
msgstr ""
@@ -5817,6 +5829,9 @@ msgid_plural "Limited to showing %d events at most"
msgstr[0] ""
msgstr[1] ""
+msgid "Linked emails (%{email_count})"
+msgstr ""
+
msgid "LinkedIn"
msgstr ""
@@ -6030,6 +6045,9 @@ msgstr ""
msgid "Members of <strong>%{project_name}</strong>"
msgstr ""
+msgid "Merge"
+msgstr ""
+
msgid "Merge Request"
msgstr ""
@@ -6940,7 +6958,7 @@ msgstr ""
msgid "Paste a machine public key here. Read more about how to generate it %{link_start}here%{link_end}"
msgstr ""
-msgid "Paste your public SSH key, which is usually contained in the file '~/.ssh/id_rsa.pub' and begins with 'ssh-rsa'. Don't use your private SSH key."
+msgid "Paste your public SSH key, which is usually contained in the file '~/.ssh/id_ed25519.pub' or '~/.ssh/id_rsa.pub' and begins with 'ssh-ed25519' or 'ssh-rsa'. Don't use your private SSH key."
msgstr ""
msgid "Path"
@@ -7474,6 +7492,9 @@ msgstr ""
msgid "Profiles|Click on icon to activate signin with one of the following services"
msgstr ""
+msgid "Profiles|Commit email"
+msgstr ""
+
msgid "Profiles|Connect"
msgstr ""
@@ -7486,6 +7507,9 @@ msgstr ""
msgid "Profiles|Current status"
msgstr ""
+msgid "Profiles|Default notification email"
+msgstr ""
+
msgid "Profiles|Delete Account"
msgstr ""
@@ -7552,6 +7576,9 @@ msgstr ""
msgid "Profiles|No file chosen"
msgstr ""
+msgid "Profiles|Notification email"
+msgstr ""
+
msgid "Profiles|Organization"
msgstr ""
@@ -7561,6 +7588,9 @@ msgstr ""
msgid "Profiles|Position and size your new avatar"
msgstr ""
+msgid "Profiles|Primary email"
+msgstr ""
+
msgid "Profiles|Private contributions"
msgstr ""
@@ -7570,6 +7600,9 @@ msgstr ""
msgid "Profiles|Public Avatar"
msgstr ""
+msgid "Profiles|Public email"
+msgstr ""
+
msgid "Profiles|Remove avatar"
msgstr ""
@@ -7612,7 +7645,7 @@ msgstr ""
msgid "Profiles|Type your %{confirmationValue} to confirm:"
msgstr ""
-msgid "Profiles|Typically starts with \"ssh-rsa …\""
+msgid "Profiles|Typically starts with \"ssh-ed25519 …\" or \"ssh-rsa …\""
msgstr ""
msgid "Profiles|Update profile settings"
@@ -8466,6 +8499,9 @@ msgstr ""
msgid "Require users to prove ownership of custom domains"
msgstr ""
+msgid "Resend confirmation email"
+msgstr ""
+
msgid "Resend invite"
msgstr ""
@@ -8870,6 +8906,9 @@ msgstr ""
msgid "Selecting a GitLab user will add a link to the GitLab user in the descriptions of issues and comments (e.g. \"By <a href=\"#\">@johnsmith</a>\"). It will also associate and/or assign these issues and comments with the selected user."
msgstr ""
+msgid "Send confirmation email"
+msgstr ""
+
msgid "Send email"
msgstr ""
@@ -10149,6 +10188,9 @@ msgstr ""
msgid "There was a problem communicating with your device."
msgstr ""
+msgid "There was a problem sending the confirmation email"
+msgstr ""
+
msgid "There was an error %{message} todo."
msgstr ""
@@ -11871,9 +11913,15 @@ msgstr ""
msgid "YouTube"
msgstr ""
+msgid "Your Commit Email will be used for web based operations, such as edits and merges."
+msgstr ""
+
msgid "Your Conversational Development Index gives an overview of how you are using GitLab from a feature perspective. View how you compare with other organizations, discover features you are not using, and learn best practices through blog posts and white papers."
msgstr ""
+msgid "Your Default Notification Email will be used for account notifications if a %{openingTag}group-specific email address%{closingTag} is not set."
+msgstr ""
+
msgid "Your GPG keys (%{count})"
msgstr ""
@@ -11883,12 +11931,18 @@ msgstr ""
msgid "Your Kubernetes cluster information on this page is still editable, but you are advised to disable and reconfigure"
msgstr ""
+msgid "Your Primary Email will be used for avatar detection."
+msgstr ""
+
msgid "Your Projects (default)"
msgstr ""
msgid "Your Projects' Activity"
msgstr ""
+msgid "Your Public Email will be displayed on your public profile."
+msgstr ""
+
msgid "Your SSH keys (%{count})"
msgstr ""
@@ -12357,9 +12411,6 @@ msgstr ""
msgid "mrWidget|The source branch will not be deleted"
msgstr ""
-msgid "mrWidget|The target branch has advanced, which invalidates the merge request pipeline. Please update the source branch and retry merging"
-msgstr ""
-
msgid "mrWidget|There are merge conflicts"
msgstr ""
diff --git a/qa/qa/ce/strategy.rb b/qa/qa/ce/strategy.rb
index 6c1820ffdc8..018a1eb1bfc 100644
--- a/qa/qa/ce/strategy.rb
+++ b/qa/qa/ce/strategy.rb
@@ -10,18 +10,11 @@ module QA
end
def perform_before_hooks
- retries ||= 0
-
# The login page could take some time to load the first time it is visited.
# We visit the login page and wait for it to properly load only once before the tests.
- QA::Runtime::Browser.visit(:gitlab, QA::Page::Main::Login)
- rescue QA::Page::Validatable::PageValidationError
- if (retries += 1) < 3
- Runtime::Logger.warn("The login page did not appear as expected. Retrying... (attempt ##{retries})")
- retry
+ QA::Support::Retrier.retry_on_exception do
+ QA::Runtime::Browser.visit(:gitlab, QA::Page::Main::Login)
end
-
- raise
end
end
end
diff --git a/qa/qa/specs/features/browser_ui/7_configure/auto_devops/create_project_with_auto_devops_spec.rb b/qa/qa/specs/features/browser_ui/7_configure/auto_devops/create_project_with_auto_devops_spec.rb
index 86ba5e819ba..5ca9ddb6b19 100644
--- a/qa/qa/specs/features/browser_ui/7_configure/auto_devops/create_project_with_auto_devops_spec.rb
+++ b/qa/qa/specs/features/browser_ui/7_configure/auto_devops/create_project_with_auto_devops_spec.rb
@@ -9,7 +9,8 @@ module QA
Page::Main::Login.perform(&:sign_in_using_credentials)
end
- describe 'Auto DevOps support', :orchestrated, :kubernetes do
+ # Failure issue: https://gitlab.com/gitlab-org/quality/nightly/issues/108
+ describe 'Auto DevOps support', :orchestrated, :kubernetes, :quarantine do
context 'when rbac is enabled' do
before(:all) do
@cluster = Service::KubernetesCluster.new.create!
diff --git a/spec/controllers/import/fogbugz_controller_spec.rb b/spec/controllers/import/fogbugz_controller_spec.rb
index f1e0923f316..f7c813576aa 100644
--- a/spec/controllers/import/fogbugz_controller_spec.rb
+++ b/spec/controllers/import/fogbugz_controller_spec.rb
@@ -11,6 +11,44 @@ describe Import::FogbugzController do
sign_in(user)
end
+ describe 'POST #callback' do
+ let(:token) { FFaker::Lorem.characters(8) }
+ let(:uri) { 'https://example.com' }
+ let(:xml_response) { %Q(<?xml version=\"1.0\" encoding=\"UTF-8\"?><response><token><![CDATA[#{token}]]></token></response>) }
+
+ it 'attempts to contact Fogbugz server' do
+ stub_request(:post, "https://example.com/api.asp").to_return(status: 200, body: xml_response, headers: {})
+
+ post :callback, params: { uri: uri, email: 'test@example.com', password: 'mypassword' }
+
+ expect(session[:fogbugz_token]).to eq(token)
+ expect(session[:fogbugz_uri]).to eq(uri)
+ expect(response).to redirect_to(new_user_map_import_fogbugz_path)
+ end
+ end
+
+ describe 'POST #create_user_map' do
+ let(:user_map) do
+ {
+ "2" => {
+ "name" => "Test User",
+ "email" => "testuser@example.com",
+ "gitlab_user" => "3"
+ }
+ }
+ end
+
+ it 'stores the user map in the session' do
+ client = double(user_map: {})
+ expect(controller).to receive(:client).and_return(client)
+
+ post :create_user_map, params: { users: user_map }
+
+ expect(session[:fogbugz_user_map]).to eq(user_map)
+ expect(response).to redirect_to(status_import_fogbugz_path)
+ end
+ end
+
describe 'GET status' do
before do
@repo = OpenStruct.new(name: 'vim')
diff --git a/spec/controllers/projects/environments/prometheus_api_controller_spec.rb b/spec/controllers/projects/environments/prometheus_api_controller_spec.rb
index d232408b775..fdef9bc5638 100644
--- a/spec/controllers/projects/environments/prometheus_api_controller_spec.rb
+++ b/spec/controllers/projects/environments/prometheus_api_controller_spec.rb
@@ -85,12 +85,12 @@ describe Projects::Environments::PrometheusApiController do
context 'with nil result' do
let(:service_result) { nil }
- it 'returns 202 accepted' do
+ it 'returns 204 no_content' do
get :proxy, params: environment_params
expect(json_response['status']).to eq('processing')
expect(json_response['message']).to eq('Not ready yet. Try again later.')
- expect(response).to have_gitlab_http_status(:accepted)
+ expect(response).to have_gitlab_http_status(:no_content)
end
end
diff --git a/spec/controllers/projects/merge_requests_controller_spec.rb b/spec/controllers/projects/merge_requests_controller_spec.rb
index f8c0ab55eb4..34cbf0c8723 100644
--- a/spec/controllers/projects/merge_requests_controller_spec.rb
+++ b/spec/controllers/projects/merge_requests_controller_spec.rb
@@ -412,7 +412,7 @@ describe Projects::MergeRequestsController do
end
end
- context 'when the pipeline succeeds is passed' do
+ context 'when merge when pipeline succeeds option is passed' do
let!(:head_pipeline) do
create(:ci_empty_pipeline, project: project, sha: merge_request.diff_head_sha, ref: merge_request.source_branch, head_pipeline_of: merge_request)
end
@@ -462,6 +462,30 @@ describe Projects::MergeRequestsController do
expect(json_response).to eq('status' => 'merge_when_pipeline_succeeds')
end
end
+
+ context 'when auto merge has not been enabled yet' do
+ it 'calls AutoMergeService#execute' do
+ expect_next_instance_of(AutoMergeService) do |service|
+ expect(service).to receive(:execute).with(merge_request, 'merge_when_pipeline_succeeds')
+ end
+
+ merge_when_pipeline_succeeds
+ end
+ end
+
+ context 'when auto merge has already been enabled' do
+ before do
+ merge_request.update!(auto_merge_enabled: true, merge_user: user)
+ end
+
+ it 'calls AutoMergeService#update' do
+ expect_next_instance_of(AutoMergeService) do |service|
+ expect(service).to receive(:update).with(merge_request)
+ end
+
+ merge_when_pipeline_succeeds
+ end
+ end
end
describe 'only_allow_merge_if_all_discussions_are_resolved? setting' do
diff --git a/spec/controllers/projects/settings/ci_cd_controller_spec.rb b/spec/controllers/projects/settings/ci_cd_controller_spec.rb
index 117b9cf7915..5bfbcf6eeb5 100644
--- a/spec/controllers/projects/settings/ci_cd_controller_spec.rb
+++ b/spec/controllers/projects/settings/ci_cd_controller_spec.rb
@@ -212,7 +212,7 @@ describe Projects::Settings::CiCdController do
subject
project.reload
- expect(project.default_git_depth).to eq(10)
+ expect(project.ci_default_git_depth).to eq(10)
end
end
end
diff --git a/spec/features/admin/admin_settings_spec.rb b/spec/features/admin/admin_settings_spec.rb
index c4dbe23f6b4..93ccb03d822 100644
--- a/spec/features/admin/admin_settings_spec.rb
+++ b/spec/features/admin/admin_settings_spec.rb
@@ -302,22 +302,22 @@ describe 'Admin updates settings' do
group = create(:group)
page.within('.as-performance-bar') do
- check 'Enable the Performance Bar'
+ check 'Enable access to the Performance Bar'
fill_in 'Allowed group', with: group.path
click_on 'Save changes'
end
expect(page).to have_content "Application settings saved successfully"
- expect(find_field('Enable the Performance Bar')).to be_checked
+ expect(find_field('Enable access to the Performance Bar')).to be_checked
expect(find_field('Allowed group').value).to eq group.path
page.within('.as-performance-bar') do
- uncheck 'Enable the Performance Bar'
+ uncheck 'Enable access to the Performance Bar'
click_on 'Save changes'
end
expect(page).to have_content 'Application settings saved successfully'
- expect(find_field('Enable the Performance Bar')).not_to be_checked
+ expect(find_field('Enable access to the Performance Bar')).not_to be_checked
expect(find_field('Allowed group').value).to be_nil
end
diff --git a/spec/features/commits_spec.rb b/spec/features/commits_spec.rb
index 2adeb37c98a..e6f44aa7d20 100644
--- a/spec/features/commits_spec.rb
+++ b/spec/features/commits_spec.rb
@@ -82,7 +82,7 @@ describe 'Commits' do
it 'shows pipeline`s data' do
expect(page).to have_content pipeline.sha[0..7]
- expect(page).to have_content pipeline.git_commit_message
+ expect(page).to have_content pipeline.git_commit_message.gsub!(/\s+/, ' ')
expect(page).to have_content pipeline.user.name
end
end
@@ -125,7 +125,7 @@ describe 'Commits' do
it 'Renders header', :js do
expect(page).to have_content pipeline.sha[0..7]
- expect(page).to have_content pipeline.git_commit_message
+ expect(page).to have_content pipeline.git_commit_message.gsub!(/\s+/, ' ')
expect(page).to have_content pipeline.user.name
expect(page).not_to have_link('Cancel running')
expect(page).not_to have_link('Retry')
@@ -147,7 +147,7 @@ describe 'Commits' do
it do
expect(page).to have_content pipeline.sha[0..7]
- expect(page).to have_content pipeline.git_commit_message
+ expect(page).to have_content pipeline.git_commit_message.gsub!(/\s+/, ' ')
expect(page).to have_content pipeline.user.name
expect(page).not_to have_link('Cancel running')
diff --git a/spec/features/ics/dashboard_issues_spec.rb b/spec/features/ics/dashboard_issues_spec.rb
index debae0ea930..b74bbf848ac 100644
--- a/spec/features/ics/dashboard_issues_spec.rb
+++ b/spec/features/ics/dashboard_issues_spec.rb
@@ -91,7 +91,7 @@ describe 'Dashboard Issues Calendar Feed' do
expect(body).to have_text("SUMMARY:test title (in #{project.full_path})")
# line length for ics is 75 chars
- expected_description = "DESCRIPTION:Find out more at #{issue_url(issue)}".insert(75, "\r\n")
+ expected_description = "DESCRIPTION:Find out more at #{issue_url(issue)}".insert(75, ' ')
expect(body).to have_text(expected_description)
expect(body).to have_text("DTSTART;VALUE=DATE:#{Date.tomorrow.strftime('%Y%m%d')}")
expect(body).to have_text("URL:#{issue_url(issue)}")
diff --git a/spec/features/ics/group_issues_spec.rb b/spec/features/ics/group_issues_spec.rb
index 4177c7f8704..86da720c8be 100644
--- a/spec/features/ics/group_issues_spec.rb
+++ b/spec/features/ics/group_issues_spec.rb
@@ -66,7 +66,7 @@ describe 'Group Issues Calendar Feed' do
expect(body).to have_text("SUMMARY:test title (in #{project.full_path})")
# line length for ics is 75 chars
- expected_description = "DESCRIPTION:Find out more at #{issue_url(issue)}".insert(75, "\r\n")
+ expected_description = "DESCRIPTION:Find out more at #{issue_url(issue)}".insert(75, ' ')
expect(body).to have_text(expected_description)
expect(body).to have_text("DTSTART;VALUE=DATE:#{Date.tomorrow.strftime('%Y%m%d')}")
expect(body).to have_text("URL:#{issue_url(issue)}")
diff --git a/spec/features/ics/project_issues_spec.rb b/spec/features/ics/project_issues_spec.rb
index 0d9844be099..37b90c666bc 100644
--- a/spec/features/ics/project_issues_spec.rb
+++ b/spec/features/ics/project_issues_spec.rb
@@ -65,7 +65,7 @@ describe 'Project Issues Calendar Feed' do
expect(body).to have_text("SUMMARY:test title (in #{project.full_path})")
# line length for ics is 75 chars
- expected_description = "DESCRIPTION:Find out more at #{issue_url(issue)}".insert(75, "\r\n")
+ expected_description = "DESCRIPTION:Find out more at #{issue_url(issue)}".insert(75, ' ')
expect(body).to have_text(expected_description)
expect(body).to have_text("DTSTART;VALUE=DATE:#{Date.tomorrow.strftime('%Y%m%d')}")
expect(body).to have_text("URL:#{issue_url(issue)}")
diff --git a/spec/features/issues_spec.rb b/spec/features/issues_spec.rb
index 5ee9425c491..5bdd9113b06 100644
--- a/spec/features/issues_spec.rb
+++ b/spec/features/issues_spec.rb
@@ -210,7 +210,7 @@ describe 'Issues' do
let(:issue) { @issue }
it 'allows filtering by issues with no specified assignee' do
- visit project_issues_path(project, assignee_id: IssuableFinder::NONE)
+ visit project_issues_path(project, assignee_id: IssuableFinder::FILTER_NONE)
expect(page).to have_content 'foobar'
expect(page).not_to have_content 'barbaz'
diff --git a/spec/features/merge_request/user_accepts_merge_request_spec.rb b/spec/features/merge_request/user_accepts_merge_request_spec.rb
index 5fa23dbb998..3d029ccec1a 100644
--- a/spec/features/merge_request/user_accepts_merge_request_spec.rb
+++ b/spec/features/merge_request/user_accepts_merge_request_spec.rb
@@ -15,8 +15,7 @@ describe 'User accepts a merge request', :js do
click_button('Merge')
- expect(page).to have_content("The changes were merged into #{merge_request.target_branch} with \
- #{merge_request.short_merge_commit_sha}")
+ expect(page).to have_content("The changes were merged into #{merge_request.target_branch} with #{merge_request.short_merge_commit_sha}")
end
context 'with removing the source branch' do
diff --git a/spec/features/merge_request/user_creates_image_diff_notes_spec.rb b/spec/features/merge_request/user_creates_image_diff_notes_spec.rb
index 5db54f42264..3a9a06a6bc3 100644
--- a/spec/features/merge_request/user_creates_image_diff_notes_spec.rb
+++ b/spec/features/merge_request/user_creates_image_diff_notes_spec.rb
@@ -313,7 +313,7 @@ describe 'Merge request > User creates image diff notes', :js do
def create_image_diff_note
expand_text = 'Click to expand it.'
- page.all('a', text: expand_text).each do |element|
+ page.all('a', text: expand_text, wait: false).each do |element|
element.click
end
diff --git a/spec/features/merge_request/user_sees_diff_spec.rb b/spec/features/merge_request/user_sees_diff_spec.rb
index 04b07525919..8dc5912b8be 100644
--- a/spec/features/merge_request/user_sees_diff_spec.rb
+++ b/spec/features/merge_request/user_sees_diff_spec.rb
@@ -43,8 +43,7 @@ describe 'Merge request > User sees diff', :js do
visit diffs_project_merge_request_path(project, merge_request)
page.within('.alert') do
- expect(page).to have_text("Too many changes to show. Plain diff Email patch To preserve
- performance only 3 of 3+ files are displayed.")
+ expect(page).to have_text("Too many changes to show. Plain diff Email patch To preserve performance only 3 of 3+ files are displayed.")
end
end
end
diff --git a/spec/features/merge_request/user_sees_merge_widget_spec.rb b/spec/features/merge_request/user_sees_merge_widget_spec.rb
index 0066e985fbb..393077a916f 100644
--- a/spec/features/merge_request/user_sees_merge_widget_spec.rb
+++ b/spec/features/merge_request/user_sees_merge_widget_spec.rb
@@ -565,7 +565,7 @@ describe 'Merge request > User sees merge widget', :js do
click_button 'subtractTest'
expect(page).to have_content('6.66')
- expect(page).to have_content(sample_java_failed_message)
+ expect(page).to have_content(sample_java_failed_message.gsub!(/\s+/, ' ').strip)
end
end
end
@@ -610,7 +610,7 @@ describe 'Merge request > User sees merge widget', :js do
click_button 'Test#sum when a is 2 and b is 2 returns summary'
expect(page).to have_content('2.22')
- expect(page).to have_content(sample_rspec_failed_message)
+ expect(page).to have_content(sample_rspec_failed_message.gsub!(/\s+/, ' ').strip)
end
end
end
diff --git a/spec/features/merge_request/user_suggests_changes_on_diff_spec.rb b/spec/features/merge_request/user_suggests_changes_on_diff_spec.rb
index 04c7f4b6c76..780de76d2c5 100644
--- a/spec/features/merge_request/user_suggests_changes_on_diff_spec.rb
+++ b/spec/features/merge_request/user_suggests_changes_on_diff_spec.rb
@@ -7,8 +7,8 @@ describe 'User comments on a diff', :js do
include RepoHelpers
def expect_suggestion_has_content(element, expected_changing_content, expected_suggested_content)
- changing_content = element.all(:css, '.line_holder.old').map(&:text)
- suggested_content = element.all(:css, '.line_holder.new').map(&:text)
+ changing_content = element.all(:css, '.line_holder.old').map { |el| el.text(normalize_ws: true) }
+ suggested_content = element.all(:css, '.line_holder.new').map { |el| el.text(normalize_ws: true) }
expect(changing_content).to eq(expected_changing_content)
expect(suggested_content).to eq(expected_suggested_content)
diff --git a/spec/features/merge_requests/user_lists_merge_requests_spec.rb b/spec/features/merge_requests/user_lists_merge_requests_spec.rb
index bd91fae1453..2dee0e26954 100644
--- a/spec/features/merge_requests/user_lists_merge_requests_spec.rb
+++ b/spec/features/merge_requests/user_lists_merge_requests_spec.rb
@@ -33,7 +33,7 @@ describe 'Merge requests > User lists merge requests' do
end
it 'filters on no assignee' do
- visit_merge_requests(project, assignee_id: IssuableFinder::NONE)
+ visit_merge_requests(project, assignee_id: IssuableFinder::FILTER_NONE)
expect(current_path).to eq(project_merge_requests_path(project))
expect(page).to have_content 'merge-test'
diff --git a/spec/features/projects/commits/user_browses_commits_spec.rb b/spec/features/projects/commits/user_browses_commits_spec.rb
index 953517cdff9..a84fee34669 100644
--- a/spec/features/projects/commits/user_browses_commits_spec.rb
+++ b/spec/features/projects/commits/user_browses_commits_spec.rb
@@ -13,7 +13,7 @@ describe 'User browses commits' do
it 'renders commit' do
visit project_commit_path(project, sample_commit.id)
- expect(page).to have_content(sample_commit.message)
+ expect(page).to have_content(sample_commit.message.gsub!(/\s+/, ' '))
.and have_content("Showing #{sample_commit.files_changed_count} changed files")
.and have_content('Side-by-side')
end
diff --git a/spec/features/projects/features_visibility_spec.rb b/spec/features/projects/features_visibility_spec.rb
index ab16fdee883..254e885ce46 100644
--- a/spec/features/projects/features_visibility_spec.rb
+++ b/spec/features/projects/features_visibility_spec.rb
@@ -68,7 +68,8 @@ describe 'Edit Project Settings' do
end
it "hides builds when disabled" do
- allow(Ability).to receive(:allowed?).with(member, :read_builds, project).and_return(false)
+ allow(Ability).to receive(:allowed?).and_return(true)
+ allow(Ability).to receive(:allowed?).with(member, :read_build, project).and_return(false)
visit project_pipelines_path(project)
diff --git a/spec/features/projects/files/undo_template_spec.rb b/spec/features/projects/files/undo_template_spec.rb
index fa785ed10ef..91618145391 100644
--- a/spec/features/projects/files/undo_template_spec.rb
+++ b/spec/features/projects/files/undo_template_spec.rb
@@ -50,7 +50,7 @@ end
def check_content_reverted(template_content)
find('.template-selectors-undo-menu .btn-info').click
expect(page).not_to have_content(template_content)
- expect(find('.template-type-selector .dropdown-toggle-text')).to have_content
+ expect(page).to have_css('.template-type-selector .dropdown-toggle-text')
end
def select_file_template(template_selector_selector, template_name)
diff --git a/spec/features/projects/files/user_creates_files_spec.rb b/spec/features/projects/files/user_creates_files_spec.rb
index 69f8bd4d319..264b288ab38 100644
--- a/spec/features/projects/files/user_creates_files_spec.rb
+++ b/spec/features/projects/files/user_creates_files_spec.rb
@@ -174,7 +174,6 @@ describe 'Projects > Files > User creates files' do
it 'creates and commit new file in forked project', :js do
expect(page).to have_selector('.file-editor')
- expect(page).to have_content
find('#editor')
execute_script("ace.edit('editor').setValue('*.rbca')")
diff --git a/spec/features/projects/labels/user_removes_labels_spec.rb b/spec/features/projects/labels/user_removes_labels_spec.rb
index c231e54decd..7f49ddf560f 100644
--- a/spec/features/projects/labels/user_removes_labels_spec.rb
+++ b/spec/features/projects/labels/user_removes_labels_spec.rb
@@ -41,7 +41,7 @@ describe "User removes labels" do
it "removes all labels" do
loop do
- li = page.first(".label-list-item")
+ li = page.first(".label-list-item", minimum: 0)
break unless li
li.find('.js-label-options-dropdown').click
diff --git a/spec/features/projects/pipelines/pipeline_spec.rb b/spec/features/projects/pipelines/pipeline_spec.rb
index 1de153db41c..77f0f237d0a 100644
--- a/spec/features/projects/pipelines/pipeline_spec.rb
+++ b/spec/features/projects/pipelines/pipeline_spec.rb
@@ -91,7 +91,7 @@ describe 'Pipeline', :js do
within '.pipeline-info' do
expect(page).to have_content("#{pipeline.statuses.count} jobs " \
- "for #{pipeline.ref} ")
+ "for #{pipeline.ref}")
expect(page).to have_link(pipeline.ref,
href: project_commits_path(pipeline.project, pipeline.ref))
end
diff --git a/spec/features/projects/settings/integration_settings_spec.rb b/spec/features/projects/settings/integration_settings_spec.rb
index 32959969f54..016ccf63f58 100644
--- a/spec/features/projects/settings/integration_settings_spec.rb
+++ b/spec/features/projects/settings/integration_settings_spec.rb
@@ -41,7 +41,7 @@ describe 'Projects > Settings > Integration settings' do
expect(page).to have_content('Issues events')
expect(page).to have_content('Confidential issues events')
expect(page).to have_content('Note events')
- expect(page).to have_content('Merge requests events')
+ expect(page).to have_content('Merge requests events')
expect(page).to have_content('Pipeline events')
expect(page).to have_content('Wiki page events')
end
diff --git a/spec/features/projects/tree/upload_file_spec.rb b/spec/features/projects/tree/upload_file_spec.rb
index dcf7d314f8e..e5dd2f40fdf 100644
--- a/spec/features/projects/tree/upload_file_spec.rb
+++ b/spec/features/projects/tree/upload_file_spec.rb
@@ -29,6 +29,6 @@ describe 'Multi-file editor upload file', :js do
attach_file('file-upload', txt_file)
expect(page).to have_selector('.multi-file-tab', text: 'doc_sample.txt')
- expect(find('.blob-editor-container .lines-content')['innerText']).to have_content(File.open(txt_file, &:readline))
+ expect(find('.blob-editor-container .lines-content')['innerText']).to have_content(File.open(txt_file, &:readline).gsub!(/\s+/, ' '))
end
end
diff --git a/spec/features/search/user_searches_for_commits_spec.rb b/spec/features/search/user_searches_for_commits_spec.rb
index 28cae444588..998f8521384 100644
--- a/spec/features/search/user_searches_for_commits_spec.rb
+++ b/spec/features/search/user_searches_for_commits_spec.rb
@@ -35,7 +35,7 @@ describe 'User searches for commits' do
fill_in('search', with: 'deadbeef')
click_button('Search')
- expect(page).to have_current_path('/search', only_path: true)
+ expect(page).to have_current_path('/search', ignore_query: true)
end
it 'finds multiple commits' do
diff --git a/spec/features/tags/master_creates_tag_spec.rb b/spec/features/tags/master_creates_tag_spec.rb
index db2970f3340..f80ddd050d7 100644
--- a/spec/features/tags/master_creates_tag_spec.rb
+++ b/spec/features/tags/master_creates_tag_spec.rb
@@ -39,7 +39,7 @@ describe 'Maintainer creates tag' do
project_tag_path(project, 'v3.0'))
expect(page).to have_content 'v3.0'
page.within 'pre.wrap' do
- expect(page).to have_content "Awesome tag message\n\n- hello\n- world"
+ expect(page).to have_content "Awesome tag message - hello - world"
end
end
diff --git a/spec/finders/issues_finder_spec.rb b/spec/finders/issues_finder_spec.rb
index 89fdaceaa9f..bf38d083ca6 100644
--- a/spec/finders/issues_finder_spec.rb
+++ b/spec/finders/issues_finder_spec.rb
@@ -241,14 +241,6 @@ describe IssuesFinder do
end
end
- context 'filtering by legacy No+Label' do
- let(:params) { { label_name: Label::NONE } }
-
- it 'returns issues with no labels' do
- expect(issues).to contain_exactly(issue1, issue3, issue4)
- end
- end
-
context 'filtering by any label' do
let(:params) { { label_name: described_class::FILTER_ANY } }
diff --git a/spec/fixtures/lib/gitlab/metrics/dashboard/schemas/metrics.json b/spec/fixtures/lib/gitlab/metrics/dashboard/schemas/metrics.json
index 2d0af57ec2c..33393805464 100644
--- a/spec/fixtures/lib/gitlab/metrics/dashboard/schemas/metrics.json
+++ b/spec/fixtures/lib/gitlab/metrics/dashboard/schemas/metrics.json
@@ -2,7 +2,8 @@
"type": "object",
"required": [
"unit",
- "label"
+ "label",
+ "prometheus_endpoint_path"
],
"oneOf": [
{ "required": ["query"] },
@@ -14,7 +15,8 @@
"query": { "type": "string" },
"unit": { "type": "string" },
"label": { "type": "string" },
- "track": { "type": "string" }
+ "track": { "type": "string" },
+ "prometheus_endpoint_path": { "type": "string" }
},
"additionalProperties": false
}
diff --git a/spec/frontend/ide/components/ide_status_list_spec.js b/spec/frontend/ide/components/ide_status_list_spec.js
new file mode 100644
index 00000000000..4e0e8a9f0e3
--- /dev/null
+++ b/spec/frontend/ide/components/ide_status_list_spec.js
@@ -0,0 +1,91 @@
+import Vuex from 'vuex';
+import { createLocalVue, shallowMount } from '@vue/test-utils';
+import IdeStatusList from '~/ide/components/ide_status_list';
+
+const TEST_FILE = {
+ name: 'lorem.md',
+ eol: 'LF',
+ editorRow: 3,
+ editorColumn: 23,
+ fileLanguage: 'markdown',
+};
+
+const localVue = createLocalVue();
+localVue.use(Vuex);
+
+describe('ide/components/ide_status_list', () => {
+ let activeFile;
+ let store;
+ let wrapper;
+
+ const createComponent = (options = {}) => {
+ store = new Vuex.Store({
+ getters: {
+ activeFile: () => activeFile,
+ },
+ });
+
+ wrapper = shallowMount(localVue.extend(IdeStatusList), {
+ localVue,
+ sync: false,
+ store,
+ ...options,
+ });
+ };
+
+ beforeEach(() => {
+ activeFile = TEST_FILE;
+ });
+
+ afterEach(() => {
+ wrapper.destroy();
+
+ store = null;
+ wrapper = null;
+ });
+
+ const getEditorPosition = file => `${file.editorRow}:${file.editorColumn}`;
+
+ describe('with regular file', () => {
+ beforeEach(() => {
+ createComponent();
+ });
+
+ it('shows file name', () => {
+ expect(wrapper.text()).toContain(TEST_FILE.name);
+ });
+
+ it('shows file eol', () => {
+ expect(wrapper.text()).toContain(TEST_FILE.name);
+ });
+
+ it('shows file editor position', () => {
+ expect(wrapper.text()).toContain(getEditorPosition(TEST_FILE));
+ });
+
+ it('shows file language', () => {
+ expect(wrapper.text()).toContain(TEST_FILE.fileLanguage);
+ });
+ });
+
+ describe('with binary file', () => {
+ beforeEach(() => {
+ activeFile.binary = true;
+ createComponent();
+ });
+
+ it('does not show file editor position', () => {
+ expect(wrapper.text()).not.toContain(getEditorPosition(TEST_FILE));
+ });
+ });
+
+ it('adds slot as child of list', () => {
+ createComponent({
+ slots: {
+ default: ['<div class="js-test">Hello</div>', '<div class="js-test">World</div>'],
+ },
+ });
+
+ expect(wrapper.find('.ide-status-list').findAll('.js-test').length).toEqual(2);
+ });
+});
diff --git a/spec/frontend/lib/utils/url_utility_spec.js b/spec/frontend/lib/utils/url_utility_spec.js
index eca240c9c18..c771984a137 100644
--- a/spec/frontend/lib/utils/url_utility_spec.js
+++ b/spec/frontend/lib/utils/url_utility_spec.js
@@ -1,5 +1,12 @@
import * as urlUtils from '~/lib/utils/url_utility';
+const setWindowLocation = value => {
+ Object.defineProperty(window, 'location', {
+ writable: true,
+ value,
+ });
+};
+
describe('URL utility', () => {
describe('webIDEUrl', () => {
afterEach(() => {
@@ -110,12 +117,9 @@ describe('URL utility', () => {
describe('getBaseURL', () => {
beforeEach(() => {
- global.window = Object.create(window);
- Object.defineProperty(window, 'location', {
- value: {
- host: 'gitlab.com',
- protocol: 'https:',
- },
+ setWindowLocation({
+ protocol: 'https:',
+ host: 'gitlab.com',
});
});
@@ -191,4 +195,32 @@ describe('URL utility', () => {
});
});
});
+
+ describe('getWebSocketProtocol', () => {
+ it.each`
+ protocol | expectation
+ ${'http:'} | ${'ws:'}
+ ${'https:'} | ${'wss:'}
+ `('returns "$expectation" with "$protocol" protocol', ({ protocol, expectation }) => {
+ setWindowLocation({
+ protocol,
+ host: 'example.com',
+ });
+
+ expect(urlUtils.getWebSocketProtocol()).toEqual(expectation);
+ });
+ });
+
+ describe('getWebSocketUrl', () => {
+ it('joins location host to path', () => {
+ setWindowLocation({
+ protocol: 'http:',
+ host: 'example.com',
+ });
+
+ const path = '/lorem/ipsum?a=bc';
+
+ expect(urlUtils.getWebSocketUrl(path)).toEqual('ws://example.com/lorem/ipsum?a=bc');
+ });
+ });
});
diff --git a/spec/frontend/repository/components/table/__snapshots__/row_spec.js.snap b/spec/frontend/repository/components/table/__snapshots__/row_spec.js.snap
index 1b4564303e4..86bfde1a28c 100644
--- a/spec/frontend/repository/components/table/__snapshots__/row_spec.js.snap
+++ b/spec/frontend/repository/components/table/__snapshots__/row_spec.js.snap
@@ -22,6 +22,8 @@ exports[`Repository table row component renders table row 1`] = `
</a>
<!---->
+
+ <!---->
</td>
<td
diff --git a/spec/frontend/repository/components/table/row_spec.js b/spec/frontend/repository/components/table/row_spec.js
index a70dc7bb866..90a502966ad 100644
--- a/spec/frontend/repository/components/table/row_spec.js
+++ b/spec/frontend/repository/components/table/row_spec.js
@@ -1,4 +1,5 @@
import { shallowMount, RouterLinkStub } from '@vue/test-utils';
+import { GlBadge } from '@gitlab/ui';
import TableRow from '~/repository/components/table/row.vue';
let vm;
@@ -98,4 +99,16 @@ describe('Repository table row component', () => {
expect(vm.find('a').attributes('href')).toEqual('https://test.com');
});
+
+ it('renders LFS badge', () => {
+ factory({
+ id: '1',
+ path: 'test',
+ type: 'commit',
+ currentPath: '/',
+ lfsOid: '1',
+ });
+
+ expect(vm.find(GlBadge).exists()).toBe(true);
+ });
});
diff --git a/spec/graphql/types/tree/blob_type_spec.rb b/spec/graphql/types/tree/blob_type_spec.rb
index b12e214ca84..22c11aff90a 100644
--- a/spec/graphql/types/tree/blob_type_spec.rb
+++ b/spec/graphql/types/tree/blob_type_spec.rb
@@ -5,5 +5,5 @@ require 'spec_helper'
describe Types::Tree::BlobType do
it { expect(described_class.graphql_name).to eq('Blob') }
- it { expect(described_class).to have_graphql_fields(:id, :name, :type, :path, :flat_path, :web_url) }
+ it { expect(described_class).to have_graphql_fields(:id, :name, :type, :path, :flat_path, :web_url, :lfs_oid) }
end
diff --git a/spec/javascripts/diffs/components/commit_item_spec.js b/spec/javascripts/diffs/components/commit_item_spec.js
index cfe0c4bad71..dc3fb16eb40 100644
--- a/spec/javascripts/diffs/components/commit_item_spec.js
+++ b/spec/javascripts/diffs/components/commit_item_spec.js
@@ -18,7 +18,7 @@ const getDescExpandElement = vm =>
vm.$el.querySelector('.commit-content .text-expander.js-toggle-button');
const getShaElement = vm => vm.$el.querySelector('.commit-sha-group');
const getAvatarElement = vm => vm.$el.querySelector('.user-avatar-link');
-const getCommitterElement = vm => vm.$el.querySelector('.commiter');
+const getCommitterElement = vm => vm.$el.querySelector('.committer');
const getCommitActionsElement = vm => vm.$el.querySelector('.commit-actions');
describe('diffs/components/commit_item', () => {
diff --git a/spec/javascripts/monitoring/charts/area_spec.js b/spec/javascripts/monitoring/charts/area_spec.js
index 56609665b88..ac7e0bb12a1 100644
--- a/spec/javascripts/monitoring/charts/area_spec.js
+++ b/spec/javascripts/monitoring/charts/area_spec.js
@@ -214,6 +214,20 @@ describe('Area component', () => {
});
});
+ describe('chartOptions', () => {
+ describe('yAxis formatter', () => {
+ let format;
+
+ beforeEach(() => {
+ format = areaChart.vm.chartOptions.yAxis.axisLabel.formatter;
+ });
+
+ it('rounds to 3 decimal places', () => {
+ expect(format(0.88888)).toBe('0.889');
+ });
+ });
+ });
+
describe('scatterSeries', () => {
it('utilizes deployment data', () => {
expect(areaChart.vm.scatterSeries.data).toEqual([
diff --git a/spec/javascripts/monitoring/dashboard_spec.js b/spec/javascripts/monitoring/dashboard_spec.js
index 1a371c3adaf..f9c3122088e 100644
--- a/spec/javascripts/monitoring/dashboard_spec.js
+++ b/spec/javascripts/monitoring/dashboard_spec.js
@@ -314,9 +314,7 @@ describe('Dashboard', () => {
});
setTimeout(() => {
- const selectedTimeWindow = component.$el.querySelector(
- '.js-time-window-dropdown [active="true"]',
- );
+ const selectedTimeWindow = component.$el.querySelector('.js-time-window-dropdown .active');
expect(selectedTimeWindow.textContent.trim()).toEqual('30 minutes');
done();
diff --git a/spec/javascripts/monitoring/mock_data.js b/spec/javascripts/monitoring/mock_data.js
index d9d8cb66749..82e42fe9ade 100644
--- a/spec/javascripts/monitoring/mock_data.js
+++ b/spec/javascripts/monitoring/mock_data.js
@@ -857,3 +857,68 @@ export const environmentData = [
updated_at: '2018-07-04T18:44:54.010Z',
},
];
+
+export const metricsDashboardResponse = {
+ dashboard: {
+ dashboard: 'Environment metrics',
+ priority: 1,
+ panel_groups: [
+ {
+ group: 'System metrics (Kubernetes)',
+ priority: 5,
+ panels: [
+ {
+ title: 'Memory Usage (Total)',
+ type: 'area-chart',
+ y_label: 'Total Memory Used',
+ weight: 4,
+ metrics: [
+ {
+ id: 'system_metrics_kubernetes_container_memory_total',
+ query_range:
+ 'avg(sum(container_memory_usage_bytes{container_name!="POD",pod_name=~"^%{ci_environment_slug}-(.*)",namespace="%{kube_namespace}"}) by (job)) without (job) /1024/1024/1024',
+ label: 'Total',
+ unit: 'GB',
+ metric_id: 12,
+ prometheus_endpoint_path: 'http://test',
+ },
+ ],
+ },
+ {
+ title: 'Core Usage (Total)',
+ type: 'area-chart',
+ y_label: 'Total Cores',
+ weight: 3,
+ metrics: [
+ {
+ id: 'system_metrics_kubernetes_container_cores_total',
+ query_range:
+ 'avg(sum(rate(container_cpu_usage_seconds_total{container_name!="POD",pod_name=~"^%{ci_environment_slug}-(.*)",namespace="%{kube_namespace}"}[15m])) by (job)) without (job)',
+ label: 'Total',
+ unit: 'cores',
+ metric_id: 13,
+ },
+ ],
+ },
+ {
+ title: 'Memory Usage (Pod average)',
+ type: 'area-chart',
+ y_label: 'Memory Used per Pod',
+ weight: 2,
+ metrics: [
+ {
+ id: 'system_metrics_kubernetes_container_memory_average',
+ query_range:
+ 'avg(sum(container_memory_usage_bytes{container_name!="POD",pod_name=~"^%{ci_environment_slug}-(.*)",namespace="%{kube_namespace}"}) by (job)) without (job) / count(avg(container_memory_usage_bytes{container_name!="POD",pod_name=~"^%{ci_environment_slug}-(.*)",namespace="%{kube_namespace}"}) without (job)) /1024/1024',
+ label: 'Pod average',
+ unit: 'MB',
+ metric_id: 14,
+ },
+ ],
+ },
+ ],
+ },
+ ],
+ },
+ status: 'success',
+};
diff --git a/spec/javascripts/monitoring/store/actions_spec.js b/spec/javascripts/monitoring/store/actions_spec.js
index a848cd24fe3..8c02e21eda2 100644
--- a/spec/javascripts/monitoring/store/actions_spec.js
+++ b/spec/javascripts/monitoring/store/actions_spec.js
@@ -3,8 +3,13 @@ import MockAdapter from 'axios-mock-adapter';
import store from '~/monitoring/stores';
import * as types from '~/monitoring/stores/mutation_types';
import {
+ fetchDashboard,
+ receiveMetricsDashboardSuccess,
+ receiveMetricsDashboardFailure,
fetchDeploymentsData,
fetchEnvironmentsData,
+ fetchPrometheusMetrics,
+ fetchPrometheusMetric,
requestMetricsData,
setEndpoints,
setGettingStartedEmptyState,
@@ -12,7 +17,12 @@ import {
import storeState from '~/monitoring/stores/state';
import testAction from 'spec/helpers/vuex_action_helper';
import { resetStore } from '../helpers';
-import { deploymentData, environmentData } from '../mock_data';
+import {
+ deploymentData,
+ environmentData,
+ metricsDashboardResponse,
+ metricsGroupsAPIResponse,
+} from '../mock_data';
describe('Monitoring store actions', () => {
let mock;
@@ -155,4 +165,158 @@ describe('Monitoring store actions', () => {
);
});
});
+
+ describe('fetchDashboard', () => {
+ let dispatch;
+ let state;
+ const response = metricsDashboardResponse;
+
+ beforeEach(() => {
+ dispatch = jasmine.createSpy();
+ state = storeState();
+ state.dashboardEndpoint = '/dashboard';
+ });
+
+ it('dispatches receive and success actions', done => {
+ const params = {};
+ mock.onGet(state.dashboardEndpoint).reply(200, response);
+
+ fetchDashboard({ state, dispatch }, params)
+ .then(() => {
+ expect(dispatch).toHaveBeenCalledWith('requestMetricsDashboard');
+ expect(dispatch).toHaveBeenCalledWith('receiveMetricsDashboardSuccess', {
+ response,
+ params,
+ });
+ done();
+ })
+ .catch(done.fail);
+ });
+
+ it('dispatches failure action', done => {
+ const params = {};
+ mock.onGet(state.dashboardEndpoint).reply(500);
+
+ fetchDashboard({ state, dispatch }, params)
+ .then(() => {
+ expect(dispatch).toHaveBeenCalledWith(
+ 'receiveMetricsDashboardFailure',
+ new Error('Request failed with status code 500'),
+ );
+ done();
+ })
+ .catch(done.fail);
+ });
+ });
+
+ describe('receiveMetricsDashboardSuccess', () => {
+ let commit;
+ let dispatch;
+
+ beforeEach(() => {
+ commit = jasmine.createSpy();
+ dispatch = jasmine.createSpy();
+ });
+
+ it('stores groups ', () => {
+ const params = {};
+ const response = metricsDashboardResponse;
+
+ receiveMetricsDashboardSuccess({ commit, dispatch }, { response, params });
+
+ expect(commit).toHaveBeenCalledWith(
+ types.RECEIVE_METRICS_DATA_SUCCESS,
+ metricsDashboardResponse.dashboard.panel_groups,
+ );
+
+ expect(dispatch).toHaveBeenCalledWith('fetchPrometheusMetrics', params);
+ });
+ });
+
+ describe('receiveMetricsDashboardFailure', () => {
+ let commit;
+
+ beforeEach(() => {
+ commit = jasmine.createSpy();
+ });
+
+ it('commits failure action', () => {
+ receiveMetricsDashboardFailure({ commit });
+
+ expect(commit).toHaveBeenCalledWith(types.RECEIVE_METRICS_DATA_FAILURE, undefined);
+ });
+
+ it('commits failure action with error', () => {
+ receiveMetricsDashboardFailure({ commit }, 'uh-oh');
+
+ expect(commit).toHaveBeenCalledWith(types.RECEIVE_METRICS_DATA_FAILURE, 'uh-oh');
+ });
+ });
+
+ describe('fetchPrometheusMetrics', () => {
+ let commit;
+ let dispatch;
+
+ beforeEach(() => {
+ commit = jasmine.createSpy();
+ dispatch = jasmine.createSpy();
+ });
+
+ it('commits empty state when state.groups is empty', done => {
+ const state = storeState();
+ const params = {};
+
+ fetchPrometheusMetrics({ state, commit, dispatch }, params)
+ .then(() => {
+ expect(commit).toHaveBeenCalledWith(types.SET_NO_DATA_EMPTY_STATE);
+ expect(dispatch).not.toHaveBeenCalled();
+ done();
+ })
+ .catch(done.fail);
+ });
+
+ it('dispatches fetchPrometheusMetric for each panel query', done => {
+ const params = {};
+ const state = storeState();
+ state.groups = metricsDashboardResponse.dashboard.panel_groups;
+
+ const metric = state.groups[0].panels[0].metrics[0];
+
+ fetchPrometheusMetrics({ state, commit, dispatch }, params)
+ .then(() => {
+ expect(dispatch.calls.count()).toEqual(3);
+ expect(dispatch).toHaveBeenCalledWith('fetchPrometheusMetric', { metric, params });
+ done();
+ })
+ .catch(done.fail);
+
+ done();
+ });
+ });
+
+ describe('fetchPrometheusMetric', () => {
+ it('commits prometheus query result', done => {
+ const commit = jasmine.createSpy();
+ const params = {
+ start: '1557216349.469',
+ end: '1557218149.469',
+ };
+ const metric = metricsDashboardResponse.dashboard.panel_groups[0].panels[0].metrics[0];
+ const state = storeState();
+
+ const data = metricsGroupsAPIResponse.data[0].metrics[0].queries[0];
+ const response = { data };
+ mock.onGet('http://test').reply(200, response);
+
+ fetchPrometheusMetric({ state, commit }, { metric, params });
+
+ setTimeout(() => {
+ expect(commit).toHaveBeenCalledWith(types.SET_QUERY_RESULT, {
+ metricId: metric.metric_id,
+ result: data.result,
+ });
+ done();
+ });
+ });
+ });
});
diff --git a/spec/javascripts/monitoring/store/mutations_spec.js b/spec/javascripts/monitoring/store/mutations_spec.js
index 882ee1dec14..02ff5847b34 100644
--- a/spec/javascripts/monitoring/store/mutations_spec.js
+++ b/spec/javascripts/monitoring/store/mutations_spec.js
@@ -1,7 +1,7 @@
import mutations from '~/monitoring/stores/mutations';
import * as types from '~/monitoring/stores/mutation_types';
import state from '~/monitoring/stores/state';
-import { metricsGroupsAPIResponse, deploymentData } from '../mock_data';
+import { metricsGroupsAPIResponse, deploymentData, metricsDashboardResponse } from '../mock_data';
describe('Monitoring mutations', () => {
let stateCopy;
@@ -11,14 +11,16 @@ describe('Monitoring mutations', () => {
});
describe(types.RECEIVE_METRICS_DATA_SUCCESS, () => {
+ let groups;
+
beforeEach(() => {
stateCopy.groups = [];
- const groups = metricsGroupsAPIResponse.data;
-
- mutations[types.RECEIVE_METRICS_DATA_SUCCESS](stateCopy, groups);
+ groups = metricsGroupsAPIResponse.data;
});
it('normalizes values', () => {
+ mutations[types.RECEIVE_METRICS_DATA_SUCCESS](stateCopy, groups);
+
const expectedTimestamp = '2017-05-25T08:22:34.925Z';
const expectedValue = 0.0010794445585559514;
const [timestamp, value] = stateCopy.groups[0].metrics[0].queries[0].result[0].values[0];
@@ -28,22 +30,27 @@ describe('Monitoring mutations', () => {
});
it('contains two groups that contains, one of which has two queries sorted by priority', () => {
+ mutations[types.RECEIVE_METRICS_DATA_SUCCESS](stateCopy, groups);
+
expect(stateCopy.groups).toBeDefined();
expect(stateCopy.groups.length).toEqual(2);
expect(stateCopy.groups[0].metrics.length).toEqual(2);
});
it('assigns queries a metric id', () => {
+ mutations[types.RECEIVE_METRICS_DATA_SUCCESS](stateCopy, groups);
+
expect(stateCopy.groups[1].metrics[0].queries[0].metricId).toEqual('100');
});
it('removes the data if all the values from a query are not defined', () => {
+ mutations[types.RECEIVE_METRICS_DATA_SUCCESS](stateCopy, groups);
+
expect(stateCopy.groups[1].metrics[0].queries[0].result.length).toEqual(0);
});
it('assigns metric id of null if metric has no id', () => {
stateCopy.groups = [];
- const groups = metricsGroupsAPIResponse.data;
const noId = groups.map(group => ({
...group,
...{
@@ -63,6 +70,26 @@ describe('Monitoring mutations', () => {
});
});
});
+
+ describe('dashboard endpoint enabled', () => {
+ const dashboardGroups = metricsDashboardResponse.dashboard.panel_groups;
+
+ beforeEach(() => {
+ stateCopy.useDashboardEndpoint = true;
+ });
+
+ it('aliases group panels to metrics for backwards compatibility', () => {
+ mutations[types.RECEIVE_METRICS_DATA_SUCCESS](stateCopy, dashboardGroups);
+
+ expect(stateCopy.groups[0].metrics[0]).toBeDefined();
+ });
+
+ it('aliases panel metrics to queries for backwards compatibility', () => {
+ mutations[types.RECEIVE_METRICS_DATA_SUCCESS](stateCopy, dashboardGroups);
+
+ expect(stateCopy.groups[0].metrics[0].queries).toBeDefined();
+ });
+ });
});
describe(types.RECEIVE_DEPLOYMENTS_DATA_SUCCESS, () => {
@@ -82,11 +109,51 @@ describe('Monitoring mutations', () => {
metricsEndpoint: 'additional_metrics.json',
environmentsEndpoint: 'environments.json',
deploymentsEndpoint: 'deployments.json',
+ dashboardEndpoint: 'dashboard.json',
});
expect(stateCopy.metricsEndpoint).toEqual('additional_metrics.json');
expect(stateCopy.environmentsEndpoint).toEqual('environments.json');
expect(stateCopy.deploymentsEndpoint).toEqual('deployments.json');
+ expect(stateCopy.dashboardEndpoint).toEqual('dashboard.json');
+ });
+ });
+
+ describe('SET_QUERY_RESULT', () => {
+ const metricId = 12;
+ const result = [{ values: [[0, 1], [1, 1], [1, 3]] }];
+
+ beforeEach(() => {
+ stateCopy.useDashboardEndpoint = true;
+ const dashboardGroups = metricsDashboardResponse.dashboard.panel_groups;
+ mutations[types.RECEIVE_METRICS_DATA_SUCCESS](stateCopy, dashboardGroups);
+ });
+
+ it('clears empty state', () => {
+ mutations[types.SET_QUERY_RESULT](stateCopy, {
+ metricId,
+ result,
+ });
+
+ expect(stateCopy.showEmptyState).toBe(false);
+ });
+
+ it('sets metricsWithData value', () => {
+ mutations[types.SET_QUERY_RESULT](stateCopy, {
+ metricId,
+ result,
+ });
+
+ expect(stateCopy.metricsWithData).toEqual([12]);
+ });
+
+ it('does not store empty results', () => {
+ mutations[types.SET_QUERY_RESULT](stateCopy, {
+ metricId,
+ result: [],
+ });
+
+ expect(stateCopy.metricsWithData).toEqual([]);
});
});
});
diff --git a/spec/javascripts/vue_mr_widget/components/states/mr_widget_merge_when_pipeline_succeeds_spec.js b/spec/javascripts/vue_mr_widget/components/states/mr_widget_auto_merge_enabled_spec.js
index 8e0415b813b..2ea8c169add 100644
--- a/spec/javascripts/vue_mr_widget/components/states/mr_widget_merge_when_pipeline_succeeds_spec.js
+++ b/spec/javascripts/vue_mr_widget/components/states/mr_widget_auto_merge_enabled_spec.js
@@ -1,17 +1,19 @@
import Vue from 'vue';
-import mwpsComponent from '~/vue_merge_request_widget/components/states/mr_widget_merge_when_pipeline_succeeds.vue';
+import autoMergeEnabledComponent from '~/vue_merge_request_widget/components/states/mr_widget_auto_merge_enabled.vue';
import MRWidgetService from '~/vue_merge_request_widget/services/mr_widget_service';
import eventHub from '~/vue_merge_request_widget/event_hub';
import mountComponent from 'spec/helpers/vue_mount_component_helper';
+import { trimText } from 'spec/helpers/text_helper';
+import { MWPS_MERGE_STRATEGY } from '~/vue_merge_request_widget/constants';
-describe('MRWidgetMergeWhenPipelineSucceeds', () => {
+describe('MRWidgetAutoMergeEnabled', () => {
let vm;
const targetBranchPath = '/foo/bar';
const targetBranch = 'foo';
const sha = '1EA2EZ34';
beforeEach(() => {
- const Component = Vue.extend(mwpsComponent);
+ const Component = Vue.extend(autoMergeEnabledComponent);
spyOn(eventHub, '$emit');
vm = mountComponent(Component, {
@@ -25,6 +27,7 @@ describe('MRWidgetMergeWhenPipelineSucceeds', () => {
sha,
targetBranchPath,
targetBranch,
+ autoMergeStrategy: MWPS_MERGE_STRATEGY,
},
service: new MRWidgetService({}),
});
@@ -66,6 +69,32 @@ describe('MRWidgetMergeWhenPipelineSucceeds', () => {
expect(vm.canRemoveSourceBranch).toBeFalsy();
});
});
+
+ describe('statusTextBeforeAuthor', () => {
+ it('should return "Set by" if the MWPS is selected', () => {
+ Vue.set(vm.mr, 'autoMergeStrategy', MWPS_MERGE_STRATEGY);
+
+ expect(vm.statusTextBeforeAuthor).toBe('Set by');
+ });
+ });
+
+ describe('statusTextAfterAuthor', () => {
+ it('should return "to be merged automatically..." if MWPS is selected', () => {
+ Vue.set(vm.mr, 'autoMergeStrategy', MWPS_MERGE_STRATEGY);
+
+ expect(vm.statusTextAfterAuthor).toBe(
+ 'to be merged automatically when the pipeline succeeds',
+ );
+ });
+ });
+
+ describe('cancelButtonText', () => {
+ it('should return "Cancel automatic merge" if MWPS is selected', () => {
+ Vue.set(vm.mr, 'autoMergeStrategy', MWPS_MERGE_STRATEGY);
+
+ expect(vm.cancelButtonText).toBe('Cancel automatic merge');
+ });
+ });
});
describe('methods', () => {
@@ -96,7 +125,7 @@ describe('MRWidgetMergeWhenPipelineSucceeds', () => {
spyOn(vm.service, 'merge').and.returnValue(
Promise.resolve({
data: {
- status: 'merge_when_pipeline_succeeds',
+ status: MWPS_MERGE_STRATEGY,
},
}),
);
@@ -106,7 +135,7 @@ describe('MRWidgetMergeWhenPipelineSucceeds', () => {
expect(eventHub.$emit).toHaveBeenCalledWith('MRWidgetUpdateRequested');
expect(vm.service.merge).toHaveBeenCalledWith({
sha,
- auto_merge_strategy: 'merge_when_pipeline_succeeds',
+ auto_merge_strategy: MWPS_MERGE_STRATEGY,
should_remove_source_branch: true,
});
done();
@@ -119,6 +148,7 @@ describe('MRWidgetMergeWhenPipelineSucceeds', () => {
it('should have correct elements', () => {
expect(vm.$el.classList.contains('mr-widget-body')).toBeTruthy();
expect(vm.$el.innerText).toContain('to be merged automatically when the pipeline succeeds');
+
expect(vm.$el.innerText).toContain('The changes will be merged into');
expect(vm.$el.innerText).toContain(targetBranch);
expect(vm.$el.innerText).toContain('The source branch will not be deleted');
@@ -174,5 +204,27 @@ describe('MRWidgetMergeWhenPipelineSucceeds', () => {
done();
});
});
+
+ it('should render the status text as "...to merged automatically" if MWPS is selected', done => {
+ Vue.set(vm.mr, 'autoMergeStrategy', MWPS_MERGE_STRATEGY);
+
+ Vue.nextTick(() => {
+ const statusText = trimText(vm.$el.querySelector('.js-status-text-after-author').innerText);
+
+ expect(statusText).toBe('to be merged automatically when the pipeline succeeds');
+ done();
+ });
+ });
+
+ it('should render the cancel button as "Cancel automatic merge" if MWPS is selected', done => {
+ Vue.set(vm.mr, 'autoMergeStrategy', MWPS_MERGE_STRATEGY);
+
+ Vue.nextTick(() => {
+ const cancelButtonText = trimText(vm.$el.querySelector('.js-cancel-auto-merge').innerText);
+
+ expect(cancelButtonText).toBe('Cancel automatic merge');
+ done();
+ });
+ });
});
});
diff --git a/spec/javascripts/vue_mr_widget/components/states/mr_widget_conflicts_spec.js b/spec/javascripts/vue_mr_widget/components/states/mr_widget_conflicts_spec.js
index 39b879612ae..55073f5537c 100644
--- a/spec/javascripts/vue_mr_widget/components/states/mr_widget_conflicts_spec.js
+++ b/spec/javascripts/vue_mr_widget/components/states/mr_widget_conflicts_spec.js
@@ -23,11 +23,78 @@ describe('MRWidgetConflicts', () => {
vm.destroy();
});
- describe('when allowed to merge', () => {
+ // There are two permissions we need to consider:
+ //
+ // 1. Is the user allowed to merge to the target branch?
+ // 2. Is the user allowed to push to the source branch?
+ //
+ // This yields 4 possible permutations that we need to test, and
+ // we test them below. A user who can push to the source
+ // branch should be allowed to resolve conflicts. This is
+ // consistent with what the backend does.
+ describe('when allowed to merge but not allowed to push to source branch', () => {
beforeEach(() => {
createComponent({
mr: {
canMerge: true,
+ canPushToSourceBranch: false,
+ conflictResolutionPath: path,
+ conflictsDocsPath: '',
+ },
+ });
+ });
+
+ it('should tell you about conflicts without bothering other people', () => {
+ expect(vm.text()).toContain('There are merge conflicts');
+ expect(vm.text()).not.toContain('ask someone with write access');
+ });
+
+ it('should not allow you to resolve the conflicts', () => {
+ expect(vm.text()).not.toContain('Resolve conflicts');
+ });
+
+ it('should have merge buttons', () => {
+ const mergeLocallyButton = vm.find('.js-merge-locally-button');
+
+ expect(mergeLocallyButton.text()).toContain('Merge locally');
+ });
+ });
+
+ describe('when not allowed to merge but allowed to push to source branch', () => {
+ beforeEach(() => {
+ createComponent({
+ mr: {
+ canMerge: false,
+ canPushToSourceBranch: true,
+ conflictResolutionPath: path,
+ conflictsDocsPath: '',
+ },
+ });
+ });
+
+ it('should tell you about conflicts', () => {
+ expect(vm.text()).toContain('There are merge conflicts');
+ expect(vm.text()).toContain('ask someone with write access');
+ });
+
+ it('should allow you to resolve the conflicts', () => {
+ const resolveButton = vm.find('.js-resolve-conflicts-button');
+
+ expect(resolveButton.text()).toContain('Resolve conflicts');
+ expect(resolveButton.attributes('href')).toEqual(path);
+ });
+
+ it('should not have merge buttons', () => {
+ expect(vm.text()).not.toContain('Merge locally');
+ });
+ });
+
+ describe('when allowed to merge and push to source branch', () => {
+ beforeEach(() => {
+ createComponent({
+ mr: {
+ canMerge: true,
+ canPushToSourceBranch: true,
conflictResolutionPath: path,
conflictsDocsPath: '',
},
@@ -53,11 +120,12 @@ describe('MRWidgetConflicts', () => {
});
});
- describe('when user does not have permission to merge', () => {
+ describe('when user does not have permission to push to source branch', () => {
it('should show proper message', () => {
createComponent({
mr: {
canMerge: false,
+ canPushToSourceBranch: false,
conflictsDocsPath: '',
},
});
@@ -74,6 +142,7 @@ describe('MRWidgetConflicts', () => {
createComponent({
mr: {
canMerge: false,
+ canPushToSourceBranch: false,
conflictsDocsPath: '',
},
});
@@ -115,6 +184,7 @@ describe('MRWidgetConflicts', () => {
createComponent({
mr: {
canMerge: true,
+ canPushToSourceBranch: true,
conflictResolutionPath: gl.TEST_HOST,
sourceBranchProtected: true,
conflictsDocsPath: '',
@@ -136,6 +206,7 @@ describe('MRWidgetConflicts', () => {
createComponent({
mr: {
canMerge: true,
+ canPushToSourceBranch: true,
conflictResolutionPath: gl.TEST_HOST,
sourceBranchProtected: false,
conflictsDocsPath: '',
diff --git a/spec/javascripts/vue_mr_widget/components/states/mr_widget_ready_to_merge_spec.js b/spec/javascripts/vue_mr_widget/components/states/mr_widget_ready_to_merge_spec.js
index 3ae773b6ccb..bb76616be56 100644
--- a/spec/javascripts/vue_mr_widget/components/states/mr_widget_ready_to_merge_spec.js
+++ b/spec/javascripts/vue_mr_widget/components/states/mr_widget_ready_to_merge_spec.js
@@ -6,6 +6,7 @@ import CommitEdit from '~/vue_merge_request_widget/components/states/commit_edit
import CommitMessageDropdown from '~/vue_merge_request_widget/components/states/commit_message_dropdown.vue';
import eventHub from '~/vue_merge_request_widget/event_hub';
import { createLocalVue, shallowMount } from '@vue/test-utils';
+import { MWPS_MERGE_STRATEGY, ATMTWPS_MERGE_STRATEGY } from '~/vue_merge_request_widget/constants';
const commitMessage = 'This is the commit message';
const squashCommitMessage = 'This is the squash commit message';
@@ -29,6 +30,8 @@ const createTestMr = customConfig => {
shouldRemoveSourceBranch: true,
canRemoveSourceBranch: false,
targetBranch: 'master',
+ preferredAutoMergeStrategy: MWPS_MERGE_STRATEGY,
+ availableAutoMergeStrategies: [MWPS_MERGE_STRATEGY],
};
Object.assign(mr, customConfig.mr);
@@ -80,7 +83,6 @@ describe('ReadyToMerge', () => {
it('should have default data', () => {
expect(vm.mergeWhenBuildSucceeds).toBeFalsy();
expect(vm.useCommitMessageWithDescription).toBeFalsy();
- expect(vm.autoMergeStrategy).toBeUndefined();
expect(vm.showCommitMessageEditor).toBeFalsy();
expect(vm.isMakingRequest).toBeFalsy();
expect(vm.isMergingImmediately).toBeFalsy();
@@ -91,47 +93,51 @@ describe('ReadyToMerge', () => {
});
describe('computed', () => {
- describe('shouldShowAutoMergeText', () => {
- it('should return true with active pipeline', () => {
- vm.mr.isPipelineActive = true;
+ describe('isAutoMergeAvailable', () => {
+ it('should return true when at least one merge strategy is available', () => {
+ vm.mr.availableAutoMergeStrategies = [MWPS_MERGE_STRATEGY];
- expect(vm.shouldShowAutoMergeText).toBeTruthy();
+ expect(vm.isAutoMergeAvailable).toBe(true);
});
- it('should return false with inactive pipeline', () => {
- vm.mr.isPipelineActive = false;
+ it('should return false when no merge strategies are available', () => {
+ vm.mr.availableAutoMergeStrategies = [];
- expect(vm.shouldShowAutoMergeText).toBeFalsy();
+ expect(vm.isAutoMergeAvailable).toBe(false);
});
});
describe('status', () => {
it('defaults to success', () => {
- vm.mr.pipeline = true;
+ Vue.set(vm.mr, 'pipeline', true);
+ Vue.set(vm.mr, 'availableAutoMergeStrategies', []);
expect(vm.status).toEqual('success');
});
it('returns failed when MR has CI but also has an unknown status', () => {
- vm.mr.hasCI = true;
+ Vue.set(vm.mr, 'hasCI', true);
expect(vm.status).toEqual('failed');
});
it('returns default when MR has no pipeline', () => {
+ Vue.set(vm.mr, 'availableAutoMergeStrategies', []);
+
expect(vm.status).toEqual('success');
});
it('returns pending when pipeline is active', () => {
- vm.mr.pipeline = {};
- vm.mr.isPipelineActive = true;
+ Vue.set(vm.mr, 'pipeline', {});
+ Vue.set(vm.mr, 'isPipelineActive', true);
expect(vm.status).toEqual('pending');
});
it('returns failed when pipeline is failed', () => {
- vm.mr.pipeline = {};
- vm.mr.isPipelineFailed = true;
+ Vue.set(vm.mr, 'pipeline', {});
+ Vue.set(vm.mr, 'isPipelineFailed', true);
+ Vue.set(vm.mr, 'availableAutoMergeStrategies', []);
expect(vm.status).toEqual('failed');
});
@@ -143,18 +149,20 @@ describe('ReadyToMerge', () => {
const inActionClass = `${defaultClass} btn-info`;
it('defaults to success class', () => {
+ Vue.set(vm.mr, 'availableAutoMergeStrategies', []);
+
expect(vm.mergeButtonClass).toEqual(defaultClass);
});
it('returns success class for success status', () => {
- vm.mr.pipeline = true;
+ Vue.set(vm.mr, 'availableAutoMergeStrategies', []);
+ Vue.set(vm.mr, 'pipeline', true);
expect(vm.mergeButtonClass).toEqual(defaultClass);
});
it('returns info class for pending status', () => {
- vm.mr.pipeline = {};
- vm.mr.isPipelineActive = true;
+ Vue.set(vm.mr, 'availableAutoMergeStrategies', [ATMTWPS_MERGE_STRATEGY]);
expect(vm.mergeButtonClass).toEqual(inActionClass);
});
@@ -198,69 +206,82 @@ describe('ReadyToMerge', () => {
});
describe('mergeButtonText', () => {
- it('should return Merge', () => {
+ it('should return "Merge" when no auto merge strategies are available', () => {
+ Vue.set(vm.mr, 'availableAutoMergeStrategies', []);
+
expect(vm.mergeButtonText).toEqual('Merge');
});
- it('should return Merge in progress', () => {
- vm.isMergingImmediately = true;
+ it('should return "Merge in progress"', () => {
+ Vue.set(vm, 'isMergingImmediately', true);
expect(vm.mergeButtonText).toEqual('Merge in progress');
});
- it('should return Merge when pipeline succeeds', () => {
- vm.isMergingImmediately = false;
- vm.mr.isPipelineActive = true;
+ it('should return "Merge when pipeline succeeds" when the MWPS auto merge strategy is available', () => {
+ Vue.set(vm, 'isMergingImmediately', false);
+ Vue.set(vm.mr, 'preferredAutoMergeStrategy', MWPS_MERGE_STRATEGY);
expect(vm.mergeButtonText).toEqual('Merge when pipeline succeeds');
});
});
+ describe('autoMergeText', () => {
+ it('should return Merge when pipeline succeeds', () => {
+ Vue.set(vm.mr, 'preferredAutoMergeStrategy', MWPS_MERGE_STRATEGY);
+
+ expect(vm.autoMergeText).toEqual('Merge when pipeline succeeds');
+ });
+ });
+
describe('shouldShowMergeOptionsDropdown', () => {
- it('should return false with initial data', () => {
- expect(vm.shouldShowMergeOptionsDropdown).toBeFalsy();
+ it('should return false when no auto merge strategies are available', () => {
+ Vue.set(vm.mr, 'availableAutoMergeStrategies', []);
+
+ expect(vm.shouldShowMergeOptionsDropdown).toBe(false);
});
- it('should return true when pipeline active', () => {
- vm.mr.isPipelineActive = true;
+ it('should return true when at least one auto merge strategy is available', () => {
+ Vue.set(vm.mr, 'availableAutoMergeStrategies', [ATMTWPS_MERGE_STRATEGY]);
- expect(vm.shouldShowMergeOptionsDropdown).toBeTruthy();
+ expect(vm.shouldShowMergeOptionsDropdown).toBe(true);
});
it('should return false when pipeline active but only merge when pipeline succeeds set in project options', () => {
- vm.mr.isPipelineActive = true;
- vm.mr.onlyAllowMergeIfPipelineSucceeds = true;
+ Vue.set(vm.mr, 'availableAutoMergeStrategies', [ATMTWPS_MERGE_STRATEGY]);
+ Vue.set(vm.mr, 'onlyAllowMergeIfPipelineSucceeds', true);
- expect(vm.shouldShowMergeOptionsDropdown).toBeFalsy();
+ expect(vm.shouldShowMergeOptionsDropdown).toBe(false);
});
});
describe('isMergeButtonDisabled', () => {
it('should return false with initial data', () => {
- vm.mr.isMergeAllowed = true;
+ Vue.set(vm.mr, 'isMergeAllowed', true);
- expect(vm.isMergeButtonDisabled).toBeFalsy();
+ expect(vm.isMergeButtonDisabled).toBe(false);
});
it('should return true when there is no commit message', () => {
- vm.mr.isMergeAllowed = true;
- vm.commitMessage = '';
+ Vue.set(vm.mr, 'isMergeAllowed', true);
+ Vue.set(vm, 'commitMessage', '');
- expect(vm.isMergeButtonDisabled).toBeTruthy();
+ expect(vm.isMergeButtonDisabled).toBe(true);
});
it('should return true if merge is not allowed', () => {
- vm.mr.isMergeAllowed = false;
- vm.mr.onlyAllowMergeIfPipelineSucceeds = true;
+ Vue.set(vm.mr, 'isMergeAllowed', false);
+ Vue.set(vm.mr, 'availableAutoMergeStrategies', []);
+ Vue.set(vm.mr, 'onlyAllowMergeIfPipelineSucceeds', true);
- expect(vm.isMergeButtonDisabled).toBeTruthy();
+ expect(vm.isMergeButtonDisabled).toBe(true);
});
it('should return true when the vm instance is making request', () => {
- vm.mr.isMergeAllowed = true;
- vm.isMakingRequest = true;
+ Vue.set(vm.mr, 'isMergeAllowed', true);
+ Vue.set(vm, 'isMakingRequest', true);
- expect(vm.isMergeButtonDisabled).toBeTruthy();
+ expect(vm.isMergeButtonDisabled).toBe(true);
});
});
});
@@ -268,31 +289,31 @@ describe('ReadyToMerge', () => {
describe('methods', () => {
describe('shouldShowMergeControls', () => {
it('should return false when an external pipeline is running and required to succeed', () => {
- vm.mr.isMergeAllowed = false;
- vm.mr.isPipelineActive = false;
+ Vue.set(vm.mr, 'isMergeAllowed', false);
+ Vue.set(vm.mr, 'availableAutoMergeStrategies', []);
- expect(vm.shouldShowMergeControls).toBeFalsy();
+ expect(vm.shouldShowMergeControls).toBe(false);
});
it('should return true when the build succeeded or build not required to succeed', () => {
- vm.mr.isMergeAllowed = true;
- vm.mr.isPipelineActive = false;
+ Vue.set(vm.mr, 'isMergeAllowed', true);
+ Vue.set(vm.mr, 'availableAutoMergeStrategies', []);
- expect(vm.shouldShowMergeControls).toBeTruthy();
+ expect(vm.shouldShowMergeControls).toBe(true);
});
it('should return true when showing the MWPS button and a pipeline is running that needs to be successful', () => {
- vm.mr.isMergeAllowed = false;
- vm.mr.isPipelineActive = true;
+ Vue.set(vm.mr, 'isMergeAllowed', false);
+ Vue.set(vm.mr, 'availableAutoMergeStrategies', [MWPS_MERGE_STRATEGY]);
- expect(vm.shouldShowMergeControls).toBeTruthy();
+ expect(vm.shouldShowMergeControls).toBe(true);
});
it('should return true when showing the MWPS button but not required for the pipeline to succeed', () => {
- vm.mr.isMergeAllowed = true;
- vm.mr.isPipelineActive = true;
+ Vue.set(vm.mr, 'isMergeAllowed', true);
+ Vue.set(vm.mr, 'availableAutoMergeStrategies', [MWPS_MERGE_STRATEGY]);
- expect(vm.shouldShowMergeControls).toBeTruthy();
+ expect(vm.shouldShowMergeControls).toBe(true);
});
});
@@ -325,7 +346,6 @@ describe('ReadyToMerge', () => {
vm.handleMergeButtonClick(true);
setTimeout(() => {
- expect(vm.autoMergeStrategy).toBe('merge_when_pipeline_succeeds');
expect(vm.isMakingRequest).toBeTruthy();
expect(eventHub.$emit).toHaveBeenCalledWith('MRWidgetUpdateRequested');
@@ -349,14 +369,13 @@ describe('ReadyToMerge', () => {
vm.handleMergeButtonClick(false, true);
setTimeout(() => {
- expect(vm.autoMergeStrategy).toBeUndefined();
expect(vm.isMakingRequest).toBeTruthy();
expect(eventHub.$emit).toHaveBeenCalledWith('FailedToMerge', undefined);
const params = vm.service.merge.calls.argsFor(0)[0];
expect(params.should_remove_source_branch).toBeTruthy();
- expect(params.merge_when_pipeline_succeeds).toBeFalsy();
+ expect(params.auto_merge_strategy).toBeUndefined();
done();
}, 333);
});
@@ -367,14 +386,13 @@ describe('ReadyToMerge', () => {
vm.handleMergeButtonClick();
setTimeout(() => {
- expect(vm.autoMergeStrategy).toBeUndefined();
expect(vm.isMakingRequest).toBeTruthy();
expect(vm.initiateMergePolling).toHaveBeenCalled();
const params = vm.service.merge.calls.argsFor(0)[0];
expect(params.should_remove_source_branch).toBeTruthy();
- expect(params.merge_when_pipeline_succeeds).toBeFalsy();
+ expect(params.auto_merge_strategy).toBeUndefined();
done();
}, 333);
});
diff --git a/spec/javascripts/vue_mr_widget/mock_data.js b/spec/javascripts/vue_mr_widget/mock_data.js
index edbd0d54151..3c9a5cece90 100644
--- a/spec/javascripts/vue_mr_widget/mock_data.js
+++ b/spec/javascripts/vue_mr_widget/mock_data.js
@@ -25,7 +25,6 @@ export default {
},
merge_status: 'can_be_merged',
merge_user_id: null,
- merge_when_pipeline_succeeds: false,
source_branch: 'daaaa',
source_branch_link: 'daaaa',
source_project_id: 19,
@@ -210,8 +209,7 @@ export default {
source_branch_path: '/root/acets-app/branches/daaaa',
conflict_resolution_ui_path: '/root/acets-app/merge_requests/22/conflicts',
remove_wip_path: '/root/acets-app/merge_requests/22/remove_wip',
- cancel_merge_when_pipeline_succeeds_path:
- '/root/acets-app/merge_requests/22/cancel_merge_when_pipeline_succeeds',
+ cancel_auto_merge_path: '/root/acets-app/merge_requests/22/cancel_auto_merge',
create_issue_to_resolve_discussions_path:
'/root/acets-app/issues/new?merge_request_to_resolve_discussions_of=22',
merge_path: '/root/acets-app/merge_requests/22/merge',
@@ -237,6 +235,9 @@ export default {
merge_request_pipelines_docs_path: '/help/ci/merge_request_pipelines/index.md',
squash: true,
visual_review_app_available: true,
+ merge_trains_enabled: true,
+ merge_trains_count: 3,
+ merge_train_index: 1,
};
export const mockStore = {
diff --git a/spec/javascripts/vue_mr_widget/mr_widget_options_spec.js b/spec/javascripts/vue_mr_widget/mr_widget_options_spec.js
index 918717c4547..08f7a17515e 100644
--- a/spec/javascripts/vue_mr_widget/mr_widget_options_spec.js
+++ b/spec/javascripts/vue_mr_widget/mr_widget_options_spec.js
@@ -222,60 +222,6 @@ describe('mrWidgetOptions', () => {
});
});
});
-
- describe('showTargetBranchAdvancedError', () => {
- describe(`when the pipeline's target_sha property doesn't exist`, () => {
- beforeEach(done => {
- Vue.set(vm.mr, 'isOpen', true);
- Vue.set(vm.mr.pipeline, 'target_sha', undefined);
- Vue.set(vm.mr, 'targetBranchSha', 'abcd');
- vm.$nextTick(done);
- });
-
- it('should be false', () => {
- expect(vm.showTargetBranchAdvancedError).toEqual(false);
- });
- });
-
- describe(`when the pipeline's target_sha matches the target branch's sha`, () => {
- beforeEach(done => {
- Vue.set(vm.mr, 'isOpen', true);
- Vue.set(vm.mr.pipeline, 'target_sha', 'abcd');
- Vue.set(vm.mr, 'targetBranchSha', 'abcd');
- vm.$nextTick(done);
- });
-
- it('should be false', () => {
- expect(vm.showTargetBranchAdvancedError).toEqual(false);
- });
- });
-
- describe(`when the merge request is not open`, () => {
- beforeEach(done => {
- Vue.set(vm.mr, 'isOpen', false);
- Vue.set(vm.mr.pipeline, 'target_sha', 'abcd');
- Vue.set(vm.mr, 'targetBranchSha', 'bcde');
- vm.$nextTick(done);
- });
-
- it('should be false', () => {
- expect(vm.showTargetBranchAdvancedError).toEqual(false);
- });
- });
-
- describe(`when the pipeline's target_sha does not match the target branch's sha`, () => {
- beforeEach(done => {
- Vue.set(vm.mr, 'isOpen', true);
- Vue.set(vm.mr.pipeline, 'target_sha', 'abcd');
- Vue.set(vm.mr, 'targetBranchSha', 'bcde');
- vm.$nextTick(done);
- });
-
- it('should be true', () => {
- expect(vm.showTargetBranchAdvancedError).toEqual(true);
- });
- });
- });
});
describe('methods', () => {
diff --git a/spec/javascripts/vue_mr_widget/stores/mr_widget_store_spec.js b/spec/javascripts/vue_mr_widget/stores/mr_widget_store_spec.js
index e2cd0f084fd..e27a506f426 100644
--- a/spec/javascripts/vue_mr_widget/stores/mr_widget_store_spec.js
+++ b/spec/javascripts/vue_mr_widget/stores/mr_widget_store_spec.js
@@ -82,5 +82,47 @@ describe('MergeRequestStore', () => {
expect(store.isNothingToMergeState).toEqual(false);
});
});
+
+ describe('mergePipelinesEnabled', () => {
+ it('should set mergePipelinesEnabled = true when merge_pipelines_enabled is true', () => {
+ store.setData({ ...mockData, merge_pipelines_enabled: true });
+
+ expect(store.mergePipelinesEnabled).toBe(true);
+ });
+
+ it('should set mergePipelinesEnabled = false when merge_pipelines_enabled is not provided', () => {
+ store.setData({ ...mockData, merge_pipelines_enabled: undefined });
+
+ expect(store.mergePipelinesEnabled).toBe(false);
+ });
+ });
+
+ describe('mergeTrainsCount', () => {
+ it('should set mergeTrainsCount when merge_trains_count is provided', () => {
+ store.setData({ ...mockData, merge_trains_count: 3 });
+
+ expect(store.mergeTrainsCount).toBe(3);
+ });
+
+ it('should set mergeTrainsCount = 0 when merge_trains_count is not provided', () => {
+ store.setData({ ...mockData, merge_trains_count: undefined });
+
+ expect(store.mergeTrainsCount).toBe(0);
+ });
+ });
+
+ describe('mergeTrainIndex', () => {
+ it('should set mergeTrainIndex when merge_train_index is provided', () => {
+ store.setData({ ...mockData, merge_train_index: 3 });
+
+ expect(store.mergeTrainIndex).toBe(3);
+ });
+
+ it('should not set mergeTrainIndex when merge_train_index is not provided', () => {
+ store.setData({ ...mockData, merge_train_index: undefined });
+
+ expect(store.mergeTrainIndex).toBeUndefined();
+ });
+ });
});
});
diff --git a/spec/javascripts/vue_shared/components/pagination/graphql_pagination_spec.js b/spec/javascripts/vue_shared/components/pagination/graphql_pagination_spec.js
new file mode 100644
index 00000000000..7445da6cdee
--- /dev/null
+++ b/spec/javascripts/vue_shared/components/pagination/graphql_pagination_spec.js
@@ -0,0 +1,70 @@
+import { shallowMount } from '@vue/test-utils';
+import GraphqlPagination from '~/vue_shared/components/pagination/graphql_pagination.vue';
+
+describe('Graphql Pagination component', () => {
+ let wrapper;
+ function factory({ hasNextPage = true, hasPreviousPage = true }) {
+ wrapper = shallowMount(GraphqlPagination, {
+ propsData: {
+ hasNextPage,
+ hasPreviousPage,
+ },
+ });
+ }
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ describe('without previous page', () => {
+ beforeEach(() => {
+ factory({ hasPreviousPage: false });
+ });
+
+ it('renders disabled previous button', () => {
+ expect(wrapper.find('.js-prev-btn').attributes().disabled).toEqual('true');
+ });
+ });
+
+ describe('with previous page', () => {
+ beforeEach(() => {
+ factory({ hasPreviousPage: true });
+ });
+
+ it('renders enabled previous button', () => {
+ expect(wrapper.find('.js-prev-btn').attributes().disabled).toEqual(undefined);
+ });
+
+ it('emits previousClicked on click', () => {
+ wrapper.find('.js-prev-btn').vm.$emit('click');
+
+ expect(wrapper.emitted().previousClicked.length).toBe(1);
+ });
+ });
+
+ describe('without next page', () => {
+ beforeEach(() => {
+ factory({ hasNextPage: false });
+ });
+
+ it('renders disabled next button', () => {
+ expect(wrapper.find('.js-next-btn').attributes().disabled).toEqual('true');
+ });
+ });
+
+ describe('with next page', () => {
+ beforeEach(() => {
+ factory({ hasNextPage: true });
+ });
+
+ it('renders enabled next button', () => {
+ expect(wrapper.find('.js-next-btn').attributes().disabled).toEqual(undefined);
+ });
+
+ it('emits nextClicked on click', () => {
+ wrapper.find('.js-next-btn').vm.$emit('click');
+
+ expect(wrapper.emitted().nextClicked.length).toBe(1);
+ });
+ });
+});
diff --git a/spec/javascripts/vue_shared/components/table_pagination_spec.js b/spec/javascripts/vue_shared/components/table_pagination_spec.js
index 42cd41381dc..42abb4d83f0 100644
--- a/spec/javascripts/vue_shared/components/table_pagination_spec.js
+++ b/spec/javascripts/vue_shared/components/table_pagination_spec.js
@@ -1,5 +1,5 @@
import Vue from 'vue';
-import paginationComp from '~/vue_shared/components/table_pagination.vue';
+import paginationComp from '~/vue_shared/components/pagination/table_pagination.vue';
describe('Pagination component', () => {
let component;
diff --git a/spec/lib/banzai/pipeline/gfm_pipeline_spec.rb b/spec/lib/banzai/pipeline/gfm_pipeline_spec.rb
index 91b0499375d..7119c826bca 100644
--- a/spec/lib/banzai/pipeline/gfm_pipeline_spec.rb
+++ b/spec/lib/banzai/pipeline/gfm_pipeline_spec.rb
@@ -117,4 +117,27 @@ describe Banzai::Pipeline::GfmPipeline do
expect(output).not_to include("javascript")
end
end
+
+ describe 'emoji in references' do
+ set(:project) { create(:project, :public) }
+ let(:emoji) { '💯' }
+
+ it 'renders a label reference with emoji inside' do
+ create(:label, project: project, name: emoji)
+
+ output = described_class.to_html("#{Label.reference_prefix}\"#{emoji}\"", project: project)
+
+ expect(output).to include(emoji)
+ expect(output).to include(Gitlab::Routing.url_helpers.project_issues_path(project, label_name: emoji))
+ end
+
+ it 'renders a milestone reference with emoji inside' do
+ milestone = create(:milestone, project: project, title: emoji)
+
+ output = described_class.to_html("#{Milestone.reference_prefix}\"#{emoji}\"", project: project)
+
+ expect(output).to include(emoji)
+ expect(output).to include(Gitlab::Routing.url_helpers.milestone_path(milestone))
+ end
+ end
end
diff --git a/spec/lib/gitlab/cluster/puma_worker_killer_observer_spec.rb b/spec/lib/gitlab/cluster/puma_worker_killer_observer_spec.rb
new file mode 100644
index 00000000000..180520b27e7
--- /dev/null
+++ b/spec/lib/gitlab/cluster/puma_worker_killer_observer_spec.rb
@@ -0,0 +1,27 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Gitlab::Cluster::PumaWorkerKillerObserver do
+ let(:counter) { Gitlab::Metrics::NullMetric.instance }
+
+ before do
+ allow(Gitlab::Metrics).to receive(:counter)
+ .with(any_args)
+ .and_return(counter)
+ end
+
+ describe '#callback' do
+ subject { described_class.new }
+
+ it 'increments timeout counter' do
+ worker = double(index: 0)
+
+ expect(counter)
+ .to receive(:increment)
+ .with({ worker: 'worker_0' })
+
+ subject.callback.call(worker)
+ end
+ end
+end
diff --git a/spec/lib/gitlab/rack_timeout_observer_spec.rb b/spec/lib/gitlab/cluster/rack_timeout_observer_spec.rb
index 3dc1a8b68fb..68e5435450c 100644
--- a/spec/lib/gitlab/rack_timeout_observer_spec.rb
+++ b/spec/lib/gitlab/cluster/rack_timeout_observer_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Gitlab::RackTimeoutObserver do
+describe Gitlab::Cluster::RackTimeoutObserver do
let(:counter) { Gitlab::Metrics::NullMetric.instance }
before do
@@ -25,7 +25,7 @@ describe Gitlab::RackTimeoutObserver do
subject { described_class.new }
- it 'increments timeout counter' do
+ it 'increments counter' do
expect(counter)
.to receive(:increment)
.with({ controller: 'foo', action: 'bar', route: nil, state: :timed_out })
@@ -45,7 +45,7 @@ describe Gitlab::RackTimeoutObserver do
subject { described_class.new }
- it 'increments timeout counter' do
+ it 'increments counter' do
allow(endpoint).to receive_message_chain('route.pattern.origin') { 'foobar' }
expect(counter)
.to receive(:increment)
@@ -54,5 +54,24 @@ describe Gitlab::RackTimeoutObserver do
subject.callback.call(env)
end
end
+
+ context 'when request is being processed' do
+ let(:endpoint) { double }
+ let(:env) do
+ {
+ ::Rack::Timeout::ENV_INFO_KEY => double(state: :active),
+ Grape::Env::API_ENDPOINT => endpoint
+ }
+ end
+
+ subject { described_class.new }
+
+ it 'does not increment counter' do
+ allow(endpoint).to receive_message_chain('route.pattern.origin') { 'foobar' }
+ expect(counter).not_to receive(:increment)
+
+ subject.callback.call(env)
+ end
+ end
end
end
diff --git a/spec/lib/gitlab/data_builder/note_spec.rb b/spec/lib/gitlab/data_builder/note_spec.rb
index b236c1a9c49..ed9a1e23529 100644
--- a/spec/lib/gitlab/data_builder/note_spec.rb
+++ b/spec/lib/gitlab/data_builder/note_spec.rb
@@ -53,6 +53,8 @@ describe Gitlab::DataBuilder::Note do
.to eq(issue.reload.hook_attrs.except('updated_at'))
expect(data[:issue]['updated_at'])
.to be >= issue.hook_attrs['updated_at']
+ expect(data[:issue]['labels'])
+ .to eq(issue.hook_attrs['labels'])
end
context 'with confidential issue' do
diff --git a/spec/lib/gitlab/gitaly_client/conflicts_service_spec.rb b/spec/lib/gitlab/gitaly_client/conflicts_service_spec.rb
index e4fe01a671f..52630ba0223 100644
--- a/spec/lib/gitlab/gitaly_client/conflicts_service_spec.rb
+++ b/spec/lib/gitlab/gitaly_client/conflicts_service_spec.rb
@@ -35,7 +35,7 @@ describe Gitlab::GitalyClient::ConflictsService do
end
let(:source_branch) { 'master' }
let(:target_branch) { 'feature' }
- let(:commit_message) { 'Solving conflicts' }
+ let(:commit_message) { 'Solving conflicts\n\nTést' }
let(:resolution) do
Gitlab::Git::Conflict::Resolution.new(user, files, commit_message)
end
@@ -51,6 +51,25 @@ describe Gitlab::GitalyClient::ConflictsService do
subject
end
+ context 'with branches with UTF-8 characters' do
+ let(:source_branch) { 'testòbranch' }
+ let(:target_branch) { 'ábranch' }
+
+ it 'handles commit messages with UTF-8 characters' do
+ allow(::Gitlab::GitalyClient).to receive(:call).and_call_original
+ expect(::Gitlab::GitalyClient).to receive(:call).with(anything, :conflicts_service, :resolve_conflicts, any_args) do |*args|
+ # Force the generation of request messages by iterating through the enumerator
+ message = args[3].to_a.first
+ params = [message.header.commit_message, message.header.source_branch, message.header.target_branch]
+ expect(params.map(&:encoding).uniq).to eq([Encoding::ASCII_8BIT])
+
+ double(resolution_error: nil)
+ end
+
+ subject
+ end
+ end
+
it 'raises a relevant exception if resolution_error is present' do
expect_any_instance_of(Gitaly::ConflictsService::Stub).to receive(:resolve_conflicts)
.with(kind_of(Enumerator), kind_of(Hash)).and_return(double(resolution_error: "something happened"))
diff --git a/spec/lib/gitlab/gitaly_client/operation_service_spec.rb b/spec/lib/gitlab/gitaly_client/operation_service_spec.rb
index 7579a6577b9..18663a72fcd 100644
--- a/spec/lib/gitlab/gitaly_client/operation_service_spec.rb
+++ b/spec/lib/gitlab/gitaly_client/operation_service_spec.rb
@@ -78,6 +78,24 @@ describe Gitlab::GitalyClient::OperationService do
subject
end
+ describe '#user_merge_to_ref' do
+ let(:branch) { 'my-branch' }
+ let(:source_sha) { 'cfe32cf61b73a0d5e9f13e774abde7ff789b1660' }
+ let(:ref) { 'refs/merge-requests/x/merge' }
+ let(:message) { 'validación' }
+ let(:response) { Gitaly::UserMergeToRefResponse.new(commit_id: 'new-commit-id') }
+
+ subject { client.user_merge_to_ref(user, source_sha, branch, ref, message) }
+
+ it 'sends a user_merge_to_ref message' do
+ expect_any_instance_of(Gitaly::OperationService::Stub)
+ .to receive(:user_merge_to_ref).with(kind_of(Gitaly::UserMergeToRefRequest), kind_of(Hash))
+ .and_return(response)
+
+ subject
+ end
+ end
+
context "when pre_receive_error is present" do
let(:response) do
Gitaly::UserUpdateBranchResponse.new(pre_receive_error: "GitLab: something failed")
diff --git a/spec/lib/gitlab/graphql/loaders/batch_lfs_oid_loader_spec.rb b/spec/lib/gitlab/graphql/loaders/batch_lfs_oid_loader_spec.rb
new file mode 100644
index 00000000000..46dd1777285
--- /dev/null
+++ b/spec/lib/gitlab/graphql/loaders/batch_lfs_oid_loader_spec.rb
@@ -0,0 +1,23 @@
+require 'spec_helper'
+
+describe Gitlab::Graphql::Loaders::BatchLfsOidLoader do
+ include GraphqlHelpers
+
+ set(:project) { create(:project, :repository) }
+ let(:repository) { project.repository }
+ let(:blob) { Gitlab::Graphql::Representation::TreeEntry.new(repository.blob_at('master', 'files/lfs/lfs_object.iso'), repository) }
+ let(:otherblob) { Gitlab::Graphql::Representation::TreeEntry.new(repository.blob_at('master', 'README'), repository) }
+
+ describe '#find' do
+ it 'batch-resolves LFS blob IDs' do
+ expect(Gitlab::Git::Blob).to receive(:batch_lfs_pointers).once.and_call_original
+
+ result = batch do
+ [blob, otherblob].map { |b| described_class.new(repository, b.id).find }
+ end
+
+ expect(result.first).to eq(blob.lfs_oid)
+ expect(result.last).to eq(nil)
+ end
+ end
+end
diff --git a/spec/lib/gitlab/import_export/project.json b/spec/lib/gitlab/import_export/project.json
index fb7bddb386c..6512fe80a3b 100644
--- a/spec/lib/gitlab/import_export/project.json
+++ b/spec/lib/gitlab/import_export/project.json
@@ -6223,7 +6223,10 @@
"erased_by_id": null,
"erased_at": null,
"type": "Ci::Build",
- "token": "abcd"
+ "token": "abcd",
+ "artifacts_file_store": 1,
+ "artifacts_metadata_store": 1,
+ "artifacts_size": 10
},
{
"id": 72,
diff --git a/spec/lib/gitlab/metrics/dashboard/finder_spec.rb b/spec/lib/gitlab/metrics/dashboard/finder_spec.rb
index e88eb140b35..bdcb5914575 100644
--- a/spec/lib/gitlab/metrics/dashboard/finder_spec.rb
+++ b/spec/lib/gitlab/metrics/dashboard/finder_spec.rb
@@ -6,7 +6,7 @@ describe Gitlab::Metrics::Dashboard::Finder, :use_clean_rails_memory_store_cachi
include MetricsDashboardHelpers
set(:project) { build(:project) }
- set(:environment) { build(:environment, project: project) }
+ set(:environment) { create(:environment, project: project) }
let(:system_dashboard_path) { Gitlab::Metrics::Dashboard::SystemDashboardService::SYSTEM_DASHBOARD_PATH}
describe '.find' do
@@ -27,6 +27,13 @@ describe Gitlab::Metrics::Dashboard::Finder, :use_clean_rails_memory_store_cachi
it_behaves_like 'misconfigured dashboard service response', :unprocessable_entity
end
+ context 'when the dashboard contains a metric without a query' do
+ let(:dashboard) { { 'panel_groups' => [{ 'panels' => [{ 'metrics' => [{ 'id' => 'mock' }] }] }] } }
+ let(:project) { project_with_dashboard(dashboard_path, dashboard.to_yaml) }
+
+ it_behaves_like 'misconfigured dashboard service response', :unprocessable_entity
+ end
+
context 'when the system dashboard is specified' do
let(:dashboard_path) { system_dashboard_path }
diff --git a/spec/lib/gitlab/metrics/dashboard/processor_spec.rb b/spec/lib/gitlab/metrics/dashboard/processor_spec.rb
index be3c1095bd7..797d4daabe3 100644
--- a/spec/lib/gitlab/metrics/dashboard/processor_spec.rb
+++ b/spec/lib/gitlab/metrics/dashboard/processor_spec.rb
@@ -4,13 +4,19 @@ require 'spec_helper'
describe Gitlab::Metrics::Dashboard::Processor do
let(:project) { build(:project) }
- let(:environment) { build(:environment, project: project) }
+ let(:environment) { create(:environment, project: project) }
let(:dashboard_yml) { YAML.load_file('spec/fixtures/lib/gitlab/metrics/dashboard/sample_dashboard.yml') }
describe 'process' do
let(:process_params) { [project, environment, dashboard_yml] }
let(:dashboard) { described_class.new(*process_params).process(insert_project_metrics: true) }
+ it 'includes a path for the prometheus endpoint with each metric' do
+ expect(all_metrics).to satisfy_all do |metric|
+ metric[:prometheus_endpoint_path] == prometheus_path(metric[:query_range])
+ end
+ end
+
context 'when dashboard config corresponds to common metrics' do
let!(:common_metric) { create(:prometheus_metric, :common, identifier: 'metric_a1') }
@@ -61,7 +67,7 @@ describe Gitlab::Metrics::Dashboard::Processor do
shared_examples_for 'errors with message' do |expected_message|
it 'raises a DashboardLayoutError' do
- error_class = Gitlab::Metrics::Dashboard::Stages::BaseStage::DashboardLayoutError
+ error_class = Gitlab::Metrics::Dashboard::Stages::BaseStage::DashboardProcessingError
expect { dashboard }.to raise_error(error_class, expected_message)
end
@@ -84,6 +90,12 @@ describe Gitlab::Metrics::Dashboard::Processor do
it_behaves_like 'errors with message', 'Each "panel" must define an array :metrics'
end
+
+ context 'when the dashboard contains a metric which is missing a query' do
+ let(:dashboard_yml) { { panel_groups: [{ panels: [{ metrics: [{}] }] }] } }
+
+ it_behaves_like 'errors with message', 'Each "metric" must define one of :query or :query_range'
+ end
end
private
@@ -99,7 +111,17 @@ describe Gitlab::Metrics::Dashboard::Processor do
query_range: metric.query,
unit: metric.unit,
label: metric.legend,
- metric_id: metric.id
+ metric_id: metric.id,
+ prometheus_endpoint_path: prometheus_path(metric.query)
}
end
+
+ def prometheus_path(query)
+ Gitlab::Routing.url_helpers.prometheus_api_project_environment_path(
+ project,
+ environment,
+ proxy_path: :query_range,
+ query: query
+ )
+ end
end
diff --git a/spec/lib/gitlab/metrics/dashboard/project_dashboard_service_spec.rb b/spec/lib/gitlab/metrics/dashboard/project_dashboard_service_spec.rb
index 162beb0268a..794ac5f109b 100644
--- a/spec/lib/gitlab/metrics/dashboard/project_dashboard_service_spec.rb
+++ b/spec/lib/gitlab/metrics/dashboard/project_dashboard_service_spec.rb
@@ -7,7 +7,7 @@ describe Gitlab::Metrics::Dashboard::ProjectDashboardService, :use_clean_rails_m
set(:user) { build(:user) }
set(:project) { build(:project) }
- set(:environment) { build(:environment, project: project) }
+ set(:environment) { create(:environment, project: project) }
before do
project.add_maintainer(user)
diff --git a/spec/lib/gitlab/metrics/dashboard/system_dashboard_service_spec.rb b/spec/lib/gitlab/metrics/dashboard/system_dashboard_service_spec.rb
index e71ce2481a3..2648fe990de 100644
--- a/spec/lib/gitlab/metrics/dashboard/system_dashboard_service_spec.rb
+++ b/spec/lib/gitlab/metrics/dashboard/system_dashboard_service_spec.rb
@@ -6,7 +6,7 @@ describe Gitlab::Metrics::Dashboard::SystemDashboardService, :use_clean_rails_me
include MetricsDashboardHelpers
set(:project) { build(:project) }
- set(:environment) { build(:environment, project: project) }
+ set(:environment) { create(:environment, project: project) }
describe 'get_dashboard' do
let(:dashboard_path) { described_class::SYSTEM_DASHBOARD_PATH }
diff --git a/spec/lib/gitlab/omniauth_initializer_spec.rb b/spec/lib/gitlab/omniauth_initializer_spec.rb
index 32296caf819..f9c0daf1ef1 100644
--- a/spec/lib/gitlab/omniauth_initializer_spec.rb
+++ b/spec/lib/gitlab/omniauth_initializer_spec.rb
@@ -83,13 +83,5 @@ describe Gitlab::OmniauthInitializer do
subject.execute([cas3_config])
end
-
- it 'configures name for openid_connect' do
- openid_connect_config = { 'name' => 'openid_connect', 'args' => {} }
-
- expect(devise_config).to receive(:omniauth).with(:openid_connect, name: 'openid_connect')
-
- subject.execute([openid_connect_config])
- end
end
end
diff --git a/spec/migrations/enqueue_reset_merge_status_spec.rb b/spec/migrations/enqueue_reset_merge_status_spec.rb
index 0d5e33bfd46..a6dd2e08079 100644
--- a/spec/migrations/enqueue_reset_merge_status_spec.rb
+++ b/spec/migrations/enqueue_reset_merge_status_spec.rb
@@ -40,9 +40,12 @@ describe EnqueueResetMergeStatus, :migration, :sidekiq do
.to be_scheduled_delayed_migration(5.minutes, 1, 2)
expect(described_class::MIGRATION)
- .to be_scheduled_delayed_migration(10.minutes, 3, 3)
+ .to be_scheduled_delayed_migration(10.minutes, 3, 4)
- expect(BackgroundMigrationWorker.jobs.size).to eq(2)
+ expect(described_class::MIGRATION)
+ .to be_scheduled_delayed_migration(15.minutes, 5, 5)
+
+ expect(BackgroundMigrationWorker.jobs.size).to eq(3)
end
end
end
diff --git a/spec/migrations/fix_pool_repository_source_project_id_spec.rb b/spec/migrations/fix_pool_repository_source_project_id_spec.rb
new file mode 100644
index 00000000000..8ddee9bb575
--- /dev/null
+++ b/spec/migrations/fix_pool_repository_source_project_id_spec.rb
@@ -0,0 +1,29 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require Rails.root.join('db', 'migrate', '20190604184643_fix_pool_repository_source_project_id.rb')
+
+describe FixPoolRepositorySourceProjectId, :migration do
+ let(:projects) { table(:projects) }
+ let(:pool_repositories) { table(:pool_repositories) }
+ let(:shards) { table(:shards) }
+
+ it 'fills in source_project_ids' do
+ shard = shards.create!(name: 'default')
+
+ # gitaly is a project with a pool repository that has a source_project_id
+ gitaly = projects.create!(name: 'gitaly', path: 'gitlab-org/gitaly', namespace_id: 1)
+ pool_repository = pool_repositories.create(shard_id: shard.id, source_project_id: gitaly.id)
+ gitaly.update_column(:pool_repository_id, pool_repository.id)
+
+ # gitlab is a project with a pool repository that's missing a source_project_id
+ pool_repository_without_source_project = pool_repositories.create(shard_id: shard.id, source_project_id: nil)
+ gitlab = projects.create!(name: 'gitlab', path: 'gitlab-org/gitlab-ce', namespace_id: 1, pool_repository_id: pool_repository_without_source_project.id)
+ projects.create!(name: 'gitlab-fork-1', path: 'my-org-1/gitlab-ce', namespace_id: 1, pool_repository_id: pool_repository_without_source_project.id)
+
+ migrate!
+
+ expect(pool_repositories.find(pool_repository_without_source_project.id).source_project_id).to eq(gitlab.id)
+ expect(pool_repositories.find(pool_repository.id).source_project_id).to eq(gitaly.id)
+ end
+end
diff --git a/spec/models/broadcast_message_spec.rb b/spec/models/broadcast_message_spec.rb
index 3ab013ddc0e..4d53e4aad8a 100644
--- a/spec/models/broadcast_message_spec.rb
+++ b/spec/models/broadcast_message_spec.rb
@@ -88,13 +88,6 @@ describe BroadcastMessage do
expect(Rails.cache).not_to receive(:delete).with(described_class::CACHE_KEY)
expect(described_class.current.length).to eq(0)
end
-
- it 'clears the legacy cache key' do
- create(:broadcast_message, :future)
-
- expect(Rails.cache).to receive(:delete).with(described_class::LEGACY_CACHE_KEY)
- expect(described_class.current.length).to eq(0)
- end
end
describe '#attributes' do
@@ -164,7 +157,6 @@ describe BroadcastMessage do
message = create(:broadcast_message)
expect(Rails.cache).to receive(:delete).with(described_class::CACHE_KEY)
- expect(Rails.cache).to receive(:delete).with(described_class::LEGACY_CACHE_KEY)
message.flush_redis_cache
end
diff --git a/spec/models/concerns/reactive_caching_spec.rb b/spec/models/concerns/reactive_caching_spec.rb
index 53df9e0bc05..7faa196623f 100644
--- a/spec/models/concerns/reactive_caching_spec.rb
+++ b/spec/models/concerns/reactive_caching_spec.rb
@@ -232,4 +232,17 @@ describe ReactiveCaching, :use_clean_rails_memory_store_caching do
end
end
end
+
+ describe 'default options' do
+ let(:cached_class) { Class.new { include ReactiveCaching } }
+
+ subject { cached_class.new }
+
+ it { expect(subject.reactive_cache_lease_timeout).to be_a(ActiveSupport::Duration) }
+ it { expect(subject.reactive_cache_refresh_interval).to be_a(ActiveSupport::Duration) }
+ it { expect(subject.reactive_cache_lifetime).to be_a(ActiveSupport::Duration) }
+
+ it { expect(subject.reactive_cache_key).to respond_to(:call) }
+ it { expect(subject.reactive_cache_worker_finder).to respond_to(:call) }
+ end
end
diff --git a/spec/models/merge_request_spec.rb b/spec/models/merge_request_spec.rb
index fc28c216b21..c6251326c22 100644
--- a/spec/models/merge_request_spec.rb
+++ b/spec/models/merge_request_spec.rb
@@ -1996,6 +1996,57 @@ describe MergeRequest do
end
end
+ describe '#check_if_can_be_merged' do
+ let(:project) { create(:project, only_allow_merge_if_pipeline_succeeds: true) }
+
+ shared_examples 'checking if can be merged' do
+ context 'when it is not broken and has no conflicts' do
+ before do
+ allow(subject).to receive(:broken?) { false }
+ allow(project.repository).to receive(:can_be_merged?).and_return(true)
+ end
+
+ it 'is marked as mergeable' do
+ expect { subject.check_if_can_be_merged }.to change { subject.merge_status }.to('can_be_merged')
+ end
+ end
+
+ context 'when broken' do
+ before do
+ allow(subject).to receive(:broken?) { true }
+ allow(project.repository).to receive(:can_be_merged?).and_return(false)
+ end
+
+ it 'becomes unmergeable' do
+ expect { subject.check_if_can_be_merged }.to change { subject.merge_status }.to('cannot_be_merged')
+ end
+ end
+
+ context 'when it has conflicts' do
+ before do
+ allow(subject).to receive(:broken?) { false }
+ allow(project.repository).to receive(:can_be_merged?).and_return(false)
+ end
+
+ it 'becomes unmergeable' do
+ expect { subject.check_if_can_be_merged }.to change { subject.merge_status }.to('cannot_be_merged')
+ end
+ end
+ end
+
+ context 'when merge_status is unchecked' do
+ subject { create(:merge_request, source_project: project, merge_status: :unchecked) }
+
+ it_behaves_like 'checking if can be merged'
+ end
+
+ context 'when merge_status is unchecked' do
+ subject { create(:merge_request, source_project: project, merge_status: :cannot_be_merged_recheck) }
+
+ it_behaves_like 'checking if can be merged'
+ end
+ end
+
describe '#mergeable?' do
let(:project) { create(:project) }
@@ -2009,7 +2060,7 @@ describe MergeRequest do
it 'return true if #mergeable_state? is true and the MR #can_be_merged? is true' do
allow(subject).to receive(:mergeable_state?) { true }
- expect(subject).to receive(:check_mergeability)
+ expect(subject).to receive(:check_if_can_be_merged)
expect(subject).to receive(:can_be_merged?) { true }
expect(subject.mergeable?).to be_truthy
@@ -2023,7 +2074,7 @@ describe MergeRequest do
it 'checks if merge request can be merged' do
allow(subject).to receive(:mergeable_ci_state?) { true }
- expect(subject).to receive(:check_mergeability)
+ expect(subject).to receive(:check_if_can_be_merged)
subject.mergeable?
end
@@ -3091,6 +3142,38 @@ describe MergeRequest do
end
end
+ describe '#mergeable_to_ref?' do
+ it 'returns true when merge request is mergeable' do
+ subject = create(:merge_request)
+
+ expect(subject.mergeable_to_ref?).to be(true)
+ end
+
+ it 'returns false when merge request is already merged' do
+ subject = create(:merge_request, :merged)
+
+ expect(subject.mergeable_to_ref?).to be(false)
+ end
+
+ it 'returns false when merge request is closed' do
+ subject = create(:merge_request, :closed)
+
+ expect(subject.mergeable_to_ref?).to be(false)
+ end
+
+ it 'returns false when merge request is work in progress' do
+ subject = create(:merge_request, title: 'WIP: The feature')
+
+ expect(subject.mergeable_to_ref?).to be(false)
+ end
+
+ it 'returns false when merge request has no commits' do
+ subject = create(:merge_request, source_branch: 'empty-branch', target_branch: 'master')
+
+ expect(subject.mergeable_to_ref?).to be(false)
+ end
+ end
+
describe '#merge_participants' do
it 'contains author' do
expect(subject.merge_participants).to eq([subject.author])
diff --git a/spec/models/notification_recipient_spec.rb b/spec/models/notification_recipient_spec.rb
index 1b1ede6b14c..20278d81f6d 100644
--- a/spec/models/notification_recipient_spec.rb
+++ b/spec/models/notification_recipient_spec.rb
@@ -91,4 +91,237 @@ describe NotificationRecipient do
end
end
end
+
+ describe '#suitable_notification_level?' do
+ context 'when notification level is mention' do
+ before do
+ user.notification_settings_for(project).mention!
+ end
+
+ context 'when type is mention' do
+ let(:recipient) { described_class.new(user, :mention, target: target, project: project) }
+
+ it 'returns true' do
+ expect(recipient.suitable_notification_level?).to eq true
+ end
+ end
+
+ context 'when type is not mention' do
+ it 'returns false' do
+ expect(recipient.suitable_notification_level?).to eq false
+ end
+ end
+ end
+
+ context 'when notification level is participating' do
+ let(:notification_setting) { user.notification_settings_for(project) }
+
+ context 'when type is participating' do
+ let(:recipient) { described_class.new(user, :participating, target: target, project: project) }
+
+ it 'returns true' do
+ expect(recipient.suitable_notification_level?).to eq true
+ end
+ end
+
+ context 'when type is mention' do
+ let(:recipient) { described_class.new(user, :mention, target: target, project: project) }
+
+ it 'returns true' do
+ expect(recipient.suitable_notification_level?).to eq true
+ end
+ end
+
+ context 'with custom action' do
+ context "when action is failed_pipeline" do
+ let(:recipient) do
+ described_class.new(
+ user,
+ :watch,
+ custom_action: :failed_pipeline,
+ target: target,
+ project: project
+ )
+ end
+
+ before do
+ notification_setting.update!(failed_pipeline: true)
+ end
+
+ it 'returns true' do
+ expect(recipient.suitable_notification_level?).to eq true
+ end
+ end
+
+ context "when action is not failed_pipeline" do
+ let(:recipient) do
+ described_class.new(
+ user,
+ :watch,
+ custom_action: :success_pipeline,
+ target: target,
+ project: project
+ )
+ end
+
+ before do
+ notification_setting.update!(success_pipeline: true)
+ end
+
+ it 'returns false' do
+ expect(recipient.suitable_notification_level?).to eq false
+ end
+ end
+ end
+ end
+
+ context 'when notification level is custom' do
+ before do
+ user.notification_settings_for(project).custom!
+ end
+
+ context 'when type is participating' do
+ let(:notification_setting) { user.notification_settings_for(project) }
+ let(:recipient) do
+ described_class.new(
+ user,
+ :participating,
+ custom_action: :new_note,
+ target: target,
+ project: project
+ )
+ end
+
+ context 'with custom event enabled' do
+ before do
+ notification_setting.update!(new_note: true)
+ end
+
+ it 'returns true' do
+ expect(recipient.suitable_notification_level?).to eq true
+ end
+ end
+
+ context 'without custom event enabled' do
+ before do
+ notification_setting.update!(new_note: false)
+ end
+
+ it 'returns true' do
+ expect(recipient.suitable_notification_level?).to eq true
+ end
+ end
+ end
+
+ context 'when type is mention' do
+ let(:notification_setting) { user.notification_settings_for(project) }
+ let(:recipient) do
+ described_class.new(
+ user,
+ :mention,
+ custom_action: :new_issue,
+ target: target,
+ project: project
+ )
+ end
+
+ context 'with custom event enabled' do
+ before do
+ notification_setting.update!(new_issue: true)
+ end
+
+ it 'returns true' do
+ expect(recipient.suitable_notification_level?).to eq true
+ end
+ end
+
+ context 'without custom event enabled' do
+ before do
+ notification_setting.update!(new_issue: false)
+ end
+
+ it 'returns true' do
+ expect(recipient.suitable_notification_level?).to eq true
+ end
+ end
+ end
+
+ context 'when type is watch' do
+ let(:notification_setting) { user.notification_settings_for(project) }
+ let(:recipient) do
+ described_class.new(
+ user,
+ :watch,
+ custom_action: :failed_pipeline,
+ target: target,
+ project: project
+ )
+ end
+
+ context 'with custom event enabled' do
+ before do
+ notification_setting.update!(failed_pipeline: true)
+ end
+
+ it 'returns true' do
+ expect(recipient.suitable_notification_level?).to eq true
+ end
+ end
+
+ context 'without custom event enabled' do
+ before do
+ notification_setting.update!(failed_pipeline: false)
+ end
+
+ it 'returns false' do
+ expect(recipient.suitable_notification_level?).to eq false
+ end
+ end
+ end
+ end
+
+ context 'when notification level is watch' do
+ before do
+ user.notification_settings_for(project).watch!
+ end
+
+ context 'when type is watch' do
+ context 'without excluded watcher events' do
+ it 'returns true' do
+ expect(recipient.suitable_notification_level?).to eq true
+ end
+ end
+
+ context 'with excluded watcher events' do
+ let(:recipient) do
+ described_class.new(user, :watch, custom_action: :issue_due, target: target, project: project)
+ end
+
+ it 'returns false' do
+ expect(recipient.suitable_notification_level?).to eq false
+ end
+ end
+ end
+
+ context 'when type is not watch' do
+ context 'without excluded watcher events' do
+ let(:recipient) { described_class.new(user, :participating, target: target, project: project) }
+
+ it 'returns true' do
+ expect(recipient.suitable_notification_level?).to eq true
+ end
+ end
+
+ context 'with excluded watcher events' do
+ let(:recipient) do
+ described_class.new(user, :participating, custom_action: :issue_due, target: target, project: project)
+ end
+
+ it 'returns true' do
+ expect(recipient.suitable_notification_level?).to eq true
+ end
+ end
+ end
+ end
+ end
end
diff --git a/spec/models/project_ci_cd_setting_spec.rb b/spec/models/project_ci_cd_setting_spec.rb
index f596cee81dc..eb3a7e527c9 100644
--- a/spec/models/project_ci_cd_setting_spec.rb
+++ b/spec/models/project_ci_cd_setting_spec.rb
@@ -48,5 +48,17 @@ describe ProjectCiCdSetting do
expect(project.reload.ci_cd_settings.default_git_depth).to eq(0)
end
+
+ context 'when feature flag :ci_set_project_default_git_depth is disabled' do
+ let(:project) { create(:project) }
+
+ before do
+ stub_feature_flags(ci_set_project_default_git_depth: { enabled: false } )
+ end
+
+ it 'does not set default value for new records' do
+ expect(project.ci_cd_settings.default_git_depth).to eq(nil)
+ end
+ end
end
end
diff --git a/spec/models/project_statistics_spec.rb b/spec/models/project_statistics_spec.rb
index 358873f9a2f..1cb49d83ffa 100644
--- a/spec/models/project_statistics_spec.rb
+++ b/spec/models/project_statistics_spec.rb
@@ -197,6 +197,18 @@ describe ProjectStatistics do
expect(statistics.storage_size).to eq 9
end
+
+ it 'works during wiki_size backfill' do
+ statistics.update!(
+ repository_size: 2,
+ wiki_size: nil,
+ lfs_objects_size: 3
+ )
+
+ statistics.reload
+
+ expect(statistics.storage_size).to eq 5
+ end
end
describe '.increment_statistic' do
diff --git a/spec/policies/project_policy_spec.rb b/spec/policies/project_policy_spec.rb
index 8075fcade5f..ed0e82ef179 100644
--- a/spec/policies/project_policy_spec.rb
+++ b/spec/policies/project_policy_spec.rb
@@ -66,7 +66,7 @@ describe ProjectPolicy do
%i[
change_namespace change_visibility_level rename_project remove_project
archive_project remove_fork_project destroy_merge_request destroy_issue
- set_issue_iid set_issue_created_at set_note_created_at
+ set_issue_iid set_issue_created_at set_issue_updated_at set_note_created_at
]
end
diff --git a/spec/presenters/ci/build_runner_presenter_spec.rb b/spec/presenters/ci/build_runner_presenter_spec.rb
index 9ed8e3a4e0a..a4234d14255 100644
--- a/spec/presenters/ci/build_runner_presenter_spec.rb
+++ b/spec/presenters/ci/build_runner_presenter_spec.rb
@@ -134,7 +134,17 @@ describe Ci::BuildRunnerPresenter do
end
it 'defaults to git depth setting for the project' do
- expect(git_depth).to eq(build.project.default_git_depth)
+ expect(git_depth).to eq(build.project.ci_default_git_depth)
+ end
+
+ context 'when feature flag :ci_project_git_depth is disabled' do
+ before do
+ stub_feature_flags(ci_project_git_depth: { enabled: false })
+ end
+
+ it 'defaults to 0' do
+ expect(git_depth).to eq(0)
+ end
end
end
diff --git a/spec/rack_servers/puma_spec.rb b/spec/rack_servers/puma_spec.rb
index 8290473821c..a4b37905af3 100644
--- a/spec/rack_servers/puma_spec.rb
+++ b/spec/rack_servers/puma_spec.rb
@@ -20,7 +20,7 @@ describe 'Puma' do
File.write(config_path, config_lines)
cmd = %W[puma -e test -C #{config_path} #{File.join(__dir__, 'configs/config.ru')}]
- @puma_master_pid = spawn(*cmd)
+ @puma_master_pid = spawn({ 'DISABLE_PUMA_WORKER_KILLER' => '1' }, *cmd)
wait_puma_boot!(@puma_master_pid, File.join(project_root, 'tmp/tests/puma-worker-ready'))
WebMock.allow_net_connect!
end
diff --git a/spec/requests/api/issues/issues_spec.rb b/spec/requests/api/issues/issues_spec.rb
index 9b9cc778fb3..f32ffd1c77b 100644
--- a/spec/requests/api/issues/issues_spec.rb
+++ b/spec/requests/api/issues/issues_spec.rb
@@ -276,14 +276,6 @@ describe API::Issues do
it 'returns issues with no assignee' do
issue2 = create(:issue, author: user2, project: project)
- get api('/issues', user), params: { assignee_id: 0, scope: 'all' }
-
- expect_paginated_array_response(issue2.id)
- end
-
- it 'returns issues with no assignee' do
- issue2 = create(:issue, author: user2, project: project)
-
get api('/issues', user), params: { assignee_id: 'None', scope: 'all' }
expect_paginated_array_response(issue2.id)
@@ -496,18 +488,6 @@ describe API::Issues do
expect_paginated_array_response(closed_issue.id)
end
-
- it 'returns an array of issues with no label when using the legacy No+Label filter' do
- get api('/issues', user), params: { labels: 'No Label' }
-
- expect_paginated_array_response(closed_issue.id)
- end
-
- it 'returns an array of issues with no label when using the legacy No+Label filter with labels param as array' do
- get api('/issues', user), params: { labels: ['No Label'] }
-
- expect_paginated_array_response(closed_issue.id)
- end
end
it 'returns an empty array if no issue matches milestone' do
diff --git a/spec/requests/api/merge_requests_spec.rb b/spec/requests/api/merge_requests_spec.rb
index 4cb4fcc890d..9f9180bc8c9 100644
--- a/spec/requests/api/merge_requests_spec.rb
+++ b/spec/requests/api/merge_requests_spec.rb
@@ -1546,65 +1546,52 @@ describe API::MergeRequests do
end
end
- describe "GET /projects/:id/merge_requests/:merge_request_iid/merge_ref" do
- before do
- merge_request.mark_as_unchecked!
- end
-
- let(:merge_request_iid) { merge_request.iid }
-
+ describe "PUT /projects/:id/merge_requests/:merge_request_iid/merge_to_ref" do
+ let(:pipeline) { create(:ci_pipeline_without_jobs) }
let(:url) do
- "/projects/#{project.id}/merge_requests/#{merge_request_iid}/merge_ref"
+ "/projects/#{project.id}/merge_requests/#{merge_request.iid}/merge_to_ref"
end
it 'returns the generated ID from the merge service in case of success' do
- get api(url, user)
+ put api(url, user), params: { merge_commit_message: 'Custom message' }
+
+ commit = project.commit(json_response['commit_id'])
expect(response).to have_gitlab_http_status(200)
- expect(json_response['commit_id']).to eq(merge_request.merge_ref_head.sha)
+ expect(json_response['commit_id']).to be_present
+ expect(commit.message).to eq('Custom message')
end
it "returns 400 if branch can't be merged" do
- merge_request.update!(merge_status: 'cannot_be_merged')
+ merge_request.update!(state: 'merged')
- get api(url, user)
+ put api(url, user)
expect(response).to have_gitlab_http_status(400)
- expect(json_response['message']).to eq('Merge request is not mergeable')
+ expect(json_response['message'])
+ .to eq("Merge request is not mergeable to #{merge_request.merge_ref_path}")
end
- context 'when user has no access to the MR' do
- let(:project) { create(:project, :private) }
- let(:merge_request) { create(:merge_request, source_project: project, target_project: project) }
-
- it 'returns 404' do
- project.add_guest(user)
+ it 'returns 403 if user has no permissions to merge to the ref' do
+ user2 = create(:user)
+ project.add_reporter(user2)
- get api(url, user)
+ put api(url, user2)
- expect(response).to have_gitlab_http_status(404)
- expect(json_response['message']).to eq('404 Not found')
- end
+ expect(response).to have_gitlab_http_status(403)
+ expect(json_response['message']).to eq('403 Forbidden')
end
- context 'when invalid merge request IID' do
- let(:merge_request_iid) { '12345' }
-
- it 'returns 404' do
- get api(url, user)
+ it 'returns 404 for an invalid merge request IID' do
+ put api("/projects/#{project.id}/merge_requests/12345/merge_to_ref", user)
- expect(response).to have_gitlab_http_status(404)
- end
+ expect(response).to have_gitlab_http_status(404)
end
- context 'when merge request ID is used instead IID' do
- let(:merge_request_iid) { merge_request.id }
-
- it 'returns 404' do
- get api(url, user)
+ it "returns 404 if the merge request id is used instead of iid" do
+ put api("/projects/#{project.id}/merge_requests/#{merge_request.id}/merge", user)
- expect(response).to have_gitlab_http_status(404)
- end
+ expect(response).to have_gitlab_http_status(404)
end
end
diff --git a/spec/requests/api/projects_spec.rb b/spec/requests/api/projects_spec.rb
index 799e84e83c1..5f7d2fa6d9c 100644
--- a/spec/requests/api/projects_spec.rb
+++ b/spec/requests/api/projects_spec.rb
@@ -1125,6 +1125,7 @@ describe API::Projects do
expect(json_response['shared_with_groups'][0]['expires_at']).to be_nil
expect(json_response['only_allow_merge_if_pipeline_succeeds']).to eq(project.only_allow_merge_if_pipeline_succeeds)
expect(json_response['only_allow_merge_if_all_discussions_are_resolved']).to eq(project.only_allow_merge_if_all_discussions_are_resolved)
+ expect(json_response['ci_default_git_depth']).to eq(project.ci_default_git_depth)
expect(json_response['merge_method']).to eq(project.merge_method.to_s)
expect(json_response['readme_url']).to eq(project.readme_url)
end
@@ -1963,6 +1964,7 @@ describe API::Projects do
snippets_enabled: true,
merge_requests_enabled: true,
merge_method: 'ff',
+ ci_default_git_depth: 20,
description: 'new description' }
put api("/projects/#{project3.id}", user4), params: project_param
diff --git a/spec/requests/api/runner_spec.rb b/spec/requests/api/runner_spec.rb
index 038c958b5cc..d9ef5edb848 100644
--- a/spec/requests/api/runner_spec.rb
+++ b/spec/requests/api/runner_spec.rb
@@ -445,7 +445,7 @@ describe API::Runner, :clean_gitlab_redis_shared_state do
'before_sha' => job.before_sha,
'ref_type' => 'branch',
'refspecs' => ["+refs/heads/#{job.ref}:refs/remotes/origin/#{job.ref}"],
- 'depth' => project.default_git_depth }
+ 'depth' => project.ci_default_git_depth }
end
let(:expected_steps) do
@@ -533,7 +533,7 @@ describe API::Runner, :clean_gitlab_redis_shared_state do
context 'when GIT_DEPTH is not specified and there is no default git depth for the project' do
before do
- project.update!(default_git_depth: nil)
+ project.update!(ci_default_git_depth: nil)
end
it 'specifies refspecs' do
@@ -593,7 +593,7 @@ describe API::Runner, :clean_gitlab_redis_shared_state do
context 'when GIT_DEPTH is not specified and there is no default git depth for the project' do
before do
- project.update!(default_git_depth: nil)
+ project.update!(ci_default_git_depth: nil)
end
it 'specifies refspecs' do
diff --git a/spec/services/auto_merge/base_service_spec.rb b/spec/services/auto_merge/base_service_spec.rb
index 197fa16961d..cd08e0b6f32 100644
--- a/spec/services/auto_merge/base_service_spec.rb
+++ b/spec/services/auto_merge/base_service_spec.rb
@@ -12,6 +12,10 @@ describe AutoMerge::BaseService do
describe '#execute' do
subject { service.execute(merge_request) }
+ before do
+ allow(AutoMergeProcessWorker).to receive(:perform_async) {}
+ end
+
it 'sets properies to the merge request' do
subject
@@ -65,6 +69,12 @@ describe AutoMerge::BaseService do
it 'returns activated strategy name' do
is_expected.to eq(AutoMergeService::STRATEGY_MERGE_WHEN_PIPELINE_SUCCEEDS.to_sym)
end
+
+ it 'calls AutoMergeProcessWorker' do
+ expect(AutoMergeProcessWorker).to receive(:perform_async).with(merge_request.id).once
+
+ subject
+ end
end
context 'when failed to save' do
@@ -82,6 +92,30 @@ describe AutoMerge::BaseService do
end
end
+ describe '#update' do
+ subject { service.update(merge_request) }
+
+ let(:merge_request) { create(:merge_request, :merge_when_pipeline_succeeds) }
+
+ context 'when merge params are specified' do
+ let(:params) do
+ {
+ 'commit_message' => "Merge branch 'patch-12' into 'master'",
+ 'sha' => "200fcc9c260f7219eaf0daba87d818f0922c5b18",
+ 'should_remove_source_branch' => false,
+ 'squash' => false,
+ 'squash_commit_message' => "Update README.md"
+ }
+ end
+
+ it 'updates merge params' do
+ expect { subject }.to change {
+ merge_request.reload.merge_params.slice(*params.keys)
+ }.from({}).to(params)
+ end
+ end
+ end
+
describe '#cancel' do
subject { service.cancel(merge_request) }
diff --git a/spec/services/auto_merge_service_spec.rb b/spec/services/auto_merge_service_spec.rb
index d0eefed3150..93a22e60498 100644
--- a/spec/services/auto_merge_service_spec.rb
+++ b/spec/services/auto_merge_service_spec.rb
@@ -10,8 +10,8 @@ describe AutoMergeService do
describe '.all_strategies' do
subject { described_class.all_strategies }
- it 'returns all strategies' do
- is_expected.to eq(AutoMergeService::STRATEGIES)
+ it 'includes merge when pipeline succeeds' do
+ is_expected.to include(AutoMergeService::STRATEGY_MERGE_WHEN_PIPELINE_SUCCEEDS)
end
end
@@ -92,6 +92,30 @@ describe AutoMergeService do
end
end
+ describe '#update' do
+ subject { service.update(merge_request) }
+
+ context 'when auto merge is enabled' do
+ let(:merge_request) { create(:merge_request, :merge_when_pipeline_succeeds) }
+
+ it 'delegates to a relevant service instance' do
+ expect_next_instance_of(AutoMerge::MergeWhenPipelineSucceedsService) do |service|
+ expect(service).to receive(:update).with(merge_request)
+ end
+
+ subject
+ end
+ end
+
+ context 'when auto merge is not enabled' do
+ let(:merge_request) { create(:merge_request) }
+
+ it 'returns failed' do
+ is_expected.to eq(:failed)
+ end
+ end
+ end
+
describe '#process' do
subject { service.process(merge_request) }
diff --git a/spec/services/ci/pipeline_schedule_service_spec.rb b/spec/services/ci/pipeline_schedule_service_spec.rb
index f2ac53cb25a..867ed0acc0d 100644
--- a/spec/services/ci/pipeline_schedule_service_spec.rb
+++ b/spec/services/ci/pipeline_schedule_service_spec.rb
@@ -24,5 +24,13 @@ describe Ci::PipelineScheduleService do
subject
end
+
+ context 'when owner is nil' do
+ let(:schedule) { create(:ci_pipeline_schedule, project: project, owner: nil) }
+
+ it 'does not raise an error' do
+ expect { subject }.not_to raise_error
+ end
+ end
end
end
diff --git a/spec/services/merge_requests/merge_to_ref_service_spec.rb b/spec/services/merge_requests/merge_to_ref_service_spec.rb
index 5d492e4b013..0ac23050caf 100644
--- a/spec/services/merge_requests/merge_to_ref_service_spec.rb
+++ b/spec/services/merge_requests/merge_to_ref_service_spec.rb
@@ -32,8 +32,10 @@ describe MergeRequests::MergeToRefService do
expect(result[:status]).to eq(:success)
expect(result[:commit_id]).to be_present
+ expect(result[:source_id]).to eq(merge_request.source_branch_sha)
+ expect(result[:target_id]).to eq(merge_request.target_branch_sha)
expect(repository.ref_exists?(target_ref)).to be(true)
- expect(ref_head.sha).to eq(result[:commit_id])
+ expect(ref_head.id).to eq(result[:commit_id])
end
end
@@ -70,6 +72,10 @@ describe MergeRequests::MergeToRefService do
let(:merge_request) { create(:merge_request, :simple) }
let(:project) { merge_request.project }
+ before do
+ project.add_maintainer(user)
+ end
+
describe '#execute' do
let(:service) do
described_class.new(project, user, commit_message: 'Awesome message',
@@ -86,12 +92,6 @@ describe MergeRequests::MergeToRefService do
it_behaves_like 'successfully evaluates pre-condition checks'
context 'commit history comparison with regular MergeService' do
- before do
- # The merge service needs an authorized user while merge-to-ref
- # doesn't.
- project.add_maintainer(user)
- end
-
let(:merge_ref_service) do
described_class.new(project, user, {})
end
@@ -136,9 +136,9 @@ describe MergeRequests::MergeToRefService do
let(:merge_method) { :merge }
it 'returns error' do
- allow(project).to receive_message_chain(:repository, :merge_to_ref) { nil }
+ allow(merge_request).to receive(:mergeable_to_ref?) { false }
- error_message = 'Conflicts detected during merge'
+ error_message = "Merge request is not mergeable to #{merge_request.merge_ref_path}"
result = service.execute(merge_request)
@@ -170,5 +170,28 @@ describe MergeRequests::MergeToRefService do
it { expect(todo).not_to be_done }
end
+
+ context 'when merge request is WIP state' do
+ it 'fails to merge' do
+ merge_request = create(:merge_request, title: 'WIP: The feature')
+
+ result = service.execute(merge_request)
+
+ expect(result[:status]).to eq(:error)
+ expect(result[:message]).to eq("Merge request is not mergeable to #{merge_request.merge_ref_path}")
+ end
+ end
+
+ it 'returns error when user has no authorization to admin the merge request' do
+ unauthorized_user = create(:user)
+ project.add_reporter(unauthorized_user)
+
+ service = described_class.new(project, unauthorized_user)
+
+ result = service.execute(merge_request)
+
+ expect(result[:status]).to eq(:error)
+ expect(result[:message]).to eq('You are not allowed to merge to this ref')
+ end
end
end
diff --git a/spec/services/merge_requests/mergeability_check_service_spec.rb b/spec/services/merge_requests/mergeability_check_service_spec.rb
deleted file mode 100644
index aa0485467ed..00000000000
--- a/spec/services/merge_requests/mergeability_check_service_spec.rb
+++ /dev/null
@@ -1,187 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-describe MergeRequests::MergeabilityCheckService do
- shared_examples_for 'unmergeable merge request' do
- it 'updates or keeps merge status as cannot_be_merged' do
- subject
-
- expect(merge_request.merge_status).to eq('cannot_be_merged')
- end
-
- it 'does not change the merge ref HEAD' do
- expect { subject }.not_to change(merge_request, :merge_ref_head)
- end
-
- it 'returns ServiceResponse.error' do
- result = subject
-
- expect(result).to be_a(ServiceResponse)
- expect(result).to be_error
- end
- end
-
- shared_examples_for 'mergeable merge request' do
- it 'updates or keeps merge status as can_be_merged' do
- subject
-
- expect(merge_request.merge_status).to eq('can_be_merged')
- end
-
- it 'updates the merge ref' do
- expect { subject }.to change(merge_request, :merge_ref_head).from(nil)
- end
-
- it 'returns ServiceResponse.success' do
- result = subject
-
- expect(result).to be_a(ServiceResponse)
- expect(result).to be_success
- end
-
- it 'ServiceResponse has merge_ref_head payload' do
- result = subject
-
- expect(result.payload.keys).to contain_exactly(:merge_ref_head)
- expect(result.payload[:merge_ref_head].keys)
- .to contain_exactly(:commit_id, :target_id, :source_id)
- end
- end
-
- describe '#execute' do
- let(:project) { create(:project, :repository) }
- let(:merge_request) { create(:merge_request, merge_status: :unchecked, source_project: project, target_project: project) }
- let(:repo) { project.repository }
-
- subject { described_class.new(merge_request).execute }
-
- before do
- project.add_developer(merge_request.author)
- end
-
- it_behaves_like 'mergeable merge request'
-
- context 'when multiple calls to the service' do
- it 'returns success' do
- subject
- result = subject
-
- expect(result).to be_a(ServiceResponse)
- expect(result.success?).to be(true)
- end
-
- it 'second call does not change the merge-ref' do
- expect { subject }.to change(merge_request, :merge_ref_head).from(nil)
- expect { subject }.not_to change(merge_request, :merge_ref_head)
- end
- end
-
- context 'when broken' do
- before do
- allow(merge_request).to receive(:broken?) { true }
- allow(project.repository).to receive(:can_be_merged?) { false }
- end
-
- it_behaves_like 'unmergeable merge request'
-
- it 'returns ServiceResponse.error' do
- result = subject
-
- expect(result).to be_a(ServiceResponse)
- expect(result.error?).to be(true)
- expect(result.message).to eq('Merge request is not mergeable')
- end
- end
-
- context 'when it has conflicts' do
- before do
- allow(merge_request).to receive(:broken?) { false }
- allow(project.repository).to receive(:can_be_merged?) { false }
- end
-
- it_behaves_like 'unmergeable merge request'
-
- it 'returns ServiceResponse.error' do
- result = subject
-
- expect(result).to be_a(ServiceResponse)
- expect(result.error?).to be(true)
- expect(result.message).to eq('Merge request is not mergeable')
- end
- end
-
- context 'when MR cannot be merged and has no merge ref' do
- before do
- merge_request.mark_as_unmergeable!
- end
-
- it_behaves_like 'unmergeable merge request'
-
- it 'returns ServiceResponse.error' do
- result = subject
-
- expect(result).to be_a(ServiceResponse)
- expect(result.error?).to be(true)
- expect(result.message).to eq('Merge request is not mergeable')
- end
- end
-
- context 'when MR cannot be merged and has outdated merge ref' do
- before do
- MergeRequests::MergeToRefService.new(project, merge_request.author).execute(merge_request)
- merge_request.mark_as_unmergeable!
- end
-
- it_behaves_like 'unmergeable merge request'
-
- it 'returns ServiceResponse.error' do
- result = subject
-
- expect(result).to be_a(ServiceResponse)
- expect(result.error?).to be(true)
- expect(result.message).to eq('Merge request is not mergeable')
- end
- end
-
- context 'when merge request is not given' do
- subject { described_class.new(nil).execute }
-
- it 'returns ServiceResponse.error' do
- result = subject
-
- expect(result).to be_a(ServiceResponse)
- expect(result.message).to eq('Invalid argument')
- end
- end
-
- context 'when read only DB' do
- it 'returns ServiceResponse.error' do
- allow(Gitlab::Database).to receive(:read_only?) { true }
-
- result = subject
-
- expect(result).to be_a(ServiceResponse)
- expect(result.message).to eq('Unsupported operation')
- end
- end
-
- context 'when MR is mergeable but merge-ref does not exists' do
- before do
- merge_request.mark_as_mergeable!
- end
-
- it 'keeps merge status as can_be_merged' do
- expect { subject }.not_to change(merge_request, :merge_status).from('can_be_merged')
- end
-
- it 'returns ServiceResponse.error' do
- result = subject
-
- expect(result).to be_a(ServiceResponse)
- expect(result.error?).to be(true)
- expect(result.message).to eq('Merge ref was not found')
- end
- end
- end
-end
diff --git a/spec/services/merge_requests/update_service_spec.rb b/spec/services/merge_requests/update_service_spec.rb
index fbfcd95e204..f566d235787 100644
--- a/spec/services/merge_requests/update_service_spec.rb
+++ b/spec/services/merge_requests/update_service_spec.rb
@@ -406,6 +406,18 @@ describe MergeRequests::UpdateService, :mailer do
expect(pending_todo.reload).to be_done
end
end
+
+ context 'when auto merge is enabled and target branch changed' do
+ before do
+ AutoMergeService.new(project, user).execute(merge_request, AutoMergeService::STRATEGY_MERGE_WHEN_PIPELINE_SUCCEEDS)
+
+ update_merge_request({ target_branch: 'target' })
+ end
+
+ it 'marks pending todos as done' do
+ expect(pending_todo.reload).to be_done
+ end
+ end
end
context 'when the merge request is relabeled' do
diff --git a/spec/services/projects/fork_service_spec.rb b/spec/services/projects/fork_service_spec.rb
index 3211a6e1310..6afc91d5e95 100644
--- a/spec/services/projects/fork_service_spec.rb
+++ b/spec/services/projects/fork_service_spec.rb
@@ -150,21 +150,21 @@ describe Projects::ForkService do
context "when origin has git depth specified" do
before do
- @from_project.update(default_git_depth: 42)
+ @from_project.update(ci_default_git_depth: 42)
end
it "inherits default_git_depth from the origin project" do
- expect(to_project.default_git_depth).to eq(42)
+ expect(to_project.ci_default_git_depth).to eq(42)
end
end
context "when origin does not define git depth" do
before do
- @from_project.update!(default_git_depth: nil)
+ @from_project.update!(ci_default_git_depth: nil)
end
it "the fork has git depth set to 0" do
- expect(to_project.default_git_depth).to eq(0)
+ expect(to_project.ci_default_git_depth).to eq(0)
end
end
end
diff --git a/spec/services/service_response_spec.rb b/spec/services/service_response_spec.rb
index e790d272e61..30bd4d6820b 100644
--- a/spec/services/service_response_spec.rb
+++ b/spec/services/service_response_spec.rb
@@ -16,13 +16,6 @@ describe ServiceResponse do
expect(response).to be_success
expect(response.message).to eq('Good orange')
end
-
- it 'creates a successful response with payload' do
- response = described_class.success(payload: { good: 'orange' })
-
- expect(response).to be_success
- expect(response.payload).to eq(good: 'orange')
- end
end
describe '.error' do
@@ -40,15 +33,6 @@ describe ServiceResponse do
expect(response.message).to eq('Bad apple')
expect(response.http_status).to eq(400)
end
-
- it 'creates a failed response with payload' do
- response = described_class.error(message: 'Bad apple',
- payload: { bad: 'apple' })
-
- expect(response).to be_error
- expect(response.message).to eq('Bad apple')
- expect(response.payload).to eq(bad: 'apple')
- end
end
describe '#success?' do
diff --git a/spec/support/capybara.rb b/spec/support/capybara.rb
index 875a9a76e12..56ac208a025 100644
--- a/spec/support/capybara.rb
+++ b/spec/support/capybara.rb
@@ -42,6 +42,9 @@ Capybara.register_driver :chrome do |app|
# Disable /dev/shm use in CI. See https://gitlab.com/gitlab-org/gitlab-ee/issues/4252
options.add_argument("disable-dev-shm-usage") if ENV['CI'] || ENV['CI_SERVER']
+ # Explicitly set user-data-dir to prevent crashes. See https://gitlab.com/gitlab-org/gitlab-ce/issues/58882#note_179811508
+ options.add_argument("user-data-dir=/tmp/chrome") if ENV['CI'] || ENV['CI_SERVER']
+
Capybara::Selenium::Driver.new(
app,
browser: :chrome,
@@ -50,9 +53,11 @@ Capybara.register_driver :chrome do |app|
)
end
+Capybara.server = :webrick
Capybara.javascript_driver = :chrome
Capybara.default_max_wait_time = timeout
Capybara.ignore_hidden_elements = true
+Capybara.default_normalize_ws = true
# Keep only the screenshots generated from the last failing test suite
Capybara::Screenshot.prune_strategy = :keep_last_run
diff --git a/spec/support/features/discussion_comments_shared_example.rb b/spec/support/features/discussion_comments_shared_example.rb
index 542f533d590..0f8af2c5d6d 100644
--- a/spec/support/features/discussion_comments_shared_example.rb
+++ b/spec/support/features/discussion_comments_shared_example.rb
@@ -84,7 +84,7 @@ shared_examples 'discussion comments' do |resource_name|
#
# if dropdown menu is not toggled (and also not present),
# it's "issue-type" dropdown
- if first(menu_selector).nil?
+ if first(menu_selector, minimum: 0).nil?
expect(find(dropdown_selector)).to have_content 'Comment'
find(toggle_selector).click
diff --git a/spec/support/shared_contexts/policies/project_policy_shared_context.rb b/spec/support/shared_contexts/policies/project_policy_shared_context.rb
index 54d9f5b15f2..1aa40dcde3d 100644
--- a/spec/support/shared_contexts/policies/project_policy_shared_context.rb
+++ b/spec/support/shared_contexts/policies/project_policy_shared_context.rb
@@ -64,7 +64,7 @@ RSpec.shared_context 'ProjectPolicy context' do
%i[
change_namespace change_visibility_level rename_project remove_project
archive_project remove_fork_project destroy_merge_request destroy_issue
- set_issue_iid set_issue_created_at set_note_created_at
+ set_issue_iid set_issue_created_at set_issue_updated_at set_note_created_at
]
end
diff --git a/spec/support/shared_examples/finders/assignees_filter_shared_examples.rb b/spec/support/shared_examples/finders/assignees_filter_shared_examples.rb
index 782a2d97746..a931c4df99f 100644
--- a/spec/support/shared_examples/finders/assignees_filter_shared_examples.rb
+++ b/spec/support/shared_examples/finders/assignees_filter_shared_examples.rb
@@ -20,12 +20,6 @@ shared_examples 'no assignee filter' do
end
it 'returns issuables not assigned to any assignee' do
- params[:assignee_id] = 0
-
- expect(issuables).to contain_exactly(*expected_issuables)
- end
-
- it 'returns issuables not assigned to any assignee' do
params[:assignee_id] = 'none'
expect(issuables).to contain_exactly(*expected_issuables)
diff --git a/spec/support/shared_examples/quick_actions/issuable/shrug_quick_action_shared_examples.rb b/spec/support/shared_examples/quick_actions/issuable/shrug_quick_action_shared_examples.rb
index 0a526808585..b592cf16f67 100644
--- a/spec/support/shared_examples/quick_actions/issuable/shrug_quick_action_shared_examples.rb
+++ b/spec/support/shared_examples/quick_actions/issuable/shrug_quick_action_shared_examples.rb
@@ -27,7 +27,7 @@ shared_examples 'shrug quick action' do |issuable_type|
expect(issuable.description).to eq "bug description\noops ¯\\_(ツ)_/¯"
expect(page).to have_content 'bug 345'
- expect(page).to have_content "bug description\noops ¯\\_(ツ)_/¯"
+ expect(page).to have_content "bug description oops ¯\\_(ツ)_/¯"
end
end
diff --git a/spec/support/shared_examples/quick_actions/issuable/tableflip_quick_action_shared_examples.rb b/spec/support/shared_examples/quick_actions/issuable/tableflip_quick_action_shared_examples.rb
index ef831e39872..c174127c4ff 100644
--- a/spec/support/shared_examples/quick_actions/issuable/tableflip_quick_action_shared_examples.rb
+++ b/spec/support/shared_examples/quick_actions/issuable/tableflip_quick_action_shared_examples.rb
@@ -27,7 +27,7 @@ shared_examples 'tableflip quick action' do |issuable_type|
expect(issuable.description).to eq "bug description\noops (╯°□°)╯︵ ┻━┻"
expect(page).to have_content 'bug 345'
- expect(page).to have_content "bug description\noops (╯°□°)╯︵ ┻━┻"
+ expect(page).to have_content "bug description oops (╯°□°)╯︵ ┻━┻"
end
end
diff --git a/spec/views/notify/pipeline_failed_email.html.haml_spec.rb b/spec/views/notify/pipeline_failed_email.html.haml_spec.rb
index d9d73f789c5..d04affc7df1 100644
--- a/spec/views/notify/pipeline_failed_email.html.haml_spec.rb
+++ b/spec/views/notify/pipeline_failed_email.html.haml_spec.rb
@@ -28,7 +28,7 @@ describe 'notify/pipeline_failed_email.html.haml' do
expect(rendered).to have_content "Your pipeline has failed"
expect(rendered).to have_content pipeline.project.name
- expect(rendered).to have_content pipeline.git_commit_message.truncate(50)
+ expect(rendered).to have_content pipeline.git_commit_message.truncate(50).gsub!(/\s+/, ' ')
expect(rendered).to have_content pipeline.commit.author_name
expect(rendered).to have_content "##{pipeline.id}"
expect(rendered).to have_content pipeline.user.name
@@ -45,7 +45,7 @@ describe 'notify/pipeline_failed_email.html.haml' do
expect(rendered).to have_content "Your pipeline has failed"
expect(rendered).to have_content pipeline.project.name
- expect(rendered).to have_content pipeline.git_commit_message.truncate(50)
+ expect(rendered).to have_content pipeline.git_commit_message.truncate(50).gsub!(/\s+/, ' ')
expect(rendered).to have_content pipeline.commit.author_name
expect(rendered).to have_content "##{pipeline.id}"
expect(rendered).to have_content "by API"
diff --git a/spec/views/notify/pipeline_failed_email.text.erb_spec.rb b/spec/views/notify/pipeline_failed_email.text.erb_spec.rb
index a7d3dc09fd4..079fb865d7b 100644
--- a/spec/views/notify/pipeline_failed_email.text.erb_spec.rb
+++ b/spec/views/notify/pipeline_failed_email.text.erb_spec.rb
@@ -30,7 +30,7 @@ describe 'notify/pipeline_failed_email.text.erb' do
expect(rendered).to have_content('Your pipeline has failed')
expect(rendered).to have_content(pipeline.project.name)
- expect(rendered).to have_content(pipeline.git_commit_message.truncate(50))
+ expect(rendered).to have_content(pipeline.git_commit_message.truncate(50).gsub!(/\s+/, ' '))
expect(rendered).to have_content(pipeline.commit.author_name)
expect(rendered).to have_content("##{pipeline.id}")
expect(rendered).to have_content(pipeline.user.name)
diff --git a/spec/views/notify/pipeline_success_email.html.haml_spec.rb b/spec/views/notify/pipeline_success_email.html.haml_spec.rb
index a793b37e412..8ee7f954d70 100644
--- a/spec/views/notify/pipeline_success_email.html.haml_spec.rb
+++ b/spec/views/notify/pipeline_success_email.html.haml_spec.rb
@@ -28,7 +28,7 @@ describe 'notify/pipeline_success_email.html.haml' do
expect(rendered).to have_content "Your pipeline has passed"
expect(rendered).to have_content pipeline.project.name
- expect(rendered).to have_content pipeline.git_commit_message.truncate(50)
+ expect(rendered).to have_content pipeline.git_commit_message.truncate(50).gsub!(/\s+/, ' ')
expect(rendered).to have_content pipeline.commit.author_name
expect(rendered).to have_content "##{pipeline.id}"
expect(rendered).to have_content pipeline.user.name
@@ -45,7 +45,7 @@ describe 'notify/pipeline_success_email.html.haml' do
expect(rendered).to have_content "Your pipeline has passed"
expect(rendered).to have_content pipeline.project.name
- expect(rendered).to have_content pipeline.git_commit_message.truncate(50)
+ expect(rendered).to have_content pipeline.git_commit_message.truncate(50).gsub!(/\s+/, ' ')
expect(rendered).to have_content pipeline.commit.author_name
expect(rendered).to have_content "##{pipeline.id}"
expect(rendered).to have_content "by API"
diff --git a/spec/views/profiles/show.html.haml_spec.rb b/spec/views/profiles/show.html.haml_spec.rb
index e89a8cb9626..9e7ac0b84fa 100644
--- a/spec/views/profiles/show.html.haml_spec.rb
+++ b/spec/views/profiles/show.html.haml_spec.rb
@@ -12,8 +12,8 @@ describe 'profiles/show' do
it 'displays the correct elements' do
render
- expect(rendered).to have_field('user_name', user.name)
- expect(rendered).to have_field('user_id', user.id)
+ expect(rendered).to have_field('user_name', with: user.name)
+ expect(rendered).to have_field('user_id', with: user.id)
end
end
end