+
{{ plan.job_name }}
@@ -81,7 +81,7 @@ export default {
-
+
{{ addNum }}
diff --git a/app/assets/javascripts/vue_shared/components/registry/registry_search.vue b/app/assets/javascripts/vue_shared/components/registry/registry_search.vue
new file mode 100644
index 00000000000..62453a25f62
--- /dev/null
+++ b/app/assets/javascripts/vue_shared/components/registry/registry_search.vue
@@ -0,0 +1,90 @@
+
+
+
+
+
+
+
+ {{ item.label }}
+
+
+
+
diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb
index 0be0281a184..3e3d751fa28 100644
--- a/app/controllers/projects_controller.rb
+++ b/app/controllers/projects_controller.rb
@@ -397,6 +397,14 @@ class ProjectsController < Projects::ApplicationController
]
end
+ def project_setting_attributes
+ %i[
+ show_default_award_emojis
+ squash_option
+ allow_editing_commit_messages
+ ]
+ end
+
def project_params_attributes
[
:allow_merge_on_skipped_pipeline,
@@ -434,11 +442,7 @@ class ProjectsController < Projects::ApplicationController
:suggestion_commit_message,
:packages_enabled,
:service_desk_enabled,
- project_setting_attributes: %i[
- show_default_award_emojis
- squash_option
- allow_editing_commit_messages
- ]
+ project_setting_attributes: project_setting_attributes
] + [project_feature_attributes: project_feature_attributes]
end
diff --git a/app/finders/deployments_finder.rb b/app/finders/deployments_finder.rb
index 4038f93cf2d..bdcf7da3bea 100644
--- a/app/finders/deployments_finder.rb
+++ b/app/finders/deployments_finder.rb
@@ -1,16 +1,26 @@
# frozen_string_literal: true
+# Arguments:
+# params:
+# project: Project model - Find deployments for this project
+# updated_after: DateTime
+# updated_before: DateTime
+# finished_after: DateTime
+# finished_before: DateTime
+# environment: String
+# status: String (see Deployment.statuses)
+# order_by: String (see ALLOWED_SORT_VALUES constant)
+# sort: String (asc | desc)
class DeploymentsFinder
- attr_reader :project, :params
+ attr_reader :params
- ALLOWED_SORT_VALUES = %w[id iid created_at updated_at ref].freeze
+ ALLOWED_SORT_VALUES = %w[id iid created_at updated_at ref finished_at].freeze
DEFAULT_SORT_VALUE = 'id'
ALLOWED_SORT_DIRECTIONS = %w[asc desc].freeze
DEFAULT_SORT_DIRECTION = 'asc'
- def initialize(project, params = {})
- @project = project
+ def initialize(params = {})
@params = params
end
@@ -19,33 +29,20 @@ class DeploymentsFinder
items = by_updated_at(items)
items = by_environment(items)
items = by_status(items)
+ items = preload_associations(items)
+ items = by_finished_between(items)
sort(items)
end
private
- # rubocop: disable CodeReuse/ActiveRecord
def init_collection
- project
- .deployments
- .includes(
- :user,
- environment: [],
- deployable: {
- job_artifacts: [],
- pipeline: {
- project: {
- route: [],
- namespace: :route
- }
- },
- project: {
- namespace: :route
- }
- }
- )
+ if params[:project]
+ params[:project].deployments
+ else
+ Deployment.none
+ end
end
- # rubocop: enable CodeReuse/ActiveRecord
# rubocop: disable CodeReuse/ActiveRecord
def sort(items)
@@ -68,6 +65,12 @@ class DeploymentsFinder
end
end
+ def by_finished_between(items)
+ items = items.finished_between(params[:finished_after], params[:finished_before].presence) if params[:finished_after].present?
+
+ items
+ end
+
def by_status(items)
return items unless params[:status].present?
@@ -87,4 +90,27 @@ class DeploymentsFinder
sort_values['id'] = sort_values.delete('created_at') if sort_values['created_at'] # Sorting by `id` produces the same result as sorting by `created_at`
end
end
+
+ # rubocop: disable CodeReuse/ActiveRecord
+ def preload_associations(scope)
+ scope.includes(
+ :user,
+ environment: [],
+ deployable: {
+ job_artifacts: [],
+ pipeline: {
+ project: {
+ route: [],
+ namespace: :route
+ }
+ },
+ project: {
+ namespace: :route
+ }
+ }
+ )
+ end
+ # rubocop: enable CodeReuse/ActiveRecord
end
+
+DeploymentsFinder.prepend_if_ee('EE::DeploymentsFinder')
diff --git a/app/helpers/in_product_marketing_helper.rb b/app/helpers/in_product_marketing_helper.rb
index 92809c6d232..a0e533d3fb8 100644
--- a/app/helpers/in_product_marketing_helper.rb
+++ b/app/helpers/in_product_marketing_helper.rb
@@ -27,11 +27,11 @@ module InProductMarketingHelper
end
def in_product_marketing_logo(track, series)
- inline_image_link('mailers/in_product_marketing', "#{track}-#{series}.png", width: '150')
+ inline_image_link('mailers/in_product_marketing', "#{track}-#{series}.png", { width: '150', style: 'width: 150px;' })
end
def about_link(folder, image, width)
- link_to inline_image_link(folder, image, { width: width, alt: s_('InProductMarketing|go to about.gitlab.com') }), 'https://about.gitlab.com/'
+ link_to inline_image_link(folder, image, { width: width, style: "width: #{width}px;", alt: s_('InProductMarketing|go to about.gitlab.com') }), 'https://about.gitlab.com/'
end
def in_product_marketing_tagline(track, series)
@@ -344,7 +344,7 @@ module InProductMarketingHelper
end
def inline_image_link(folder, image, **options)
- attachments[image] = File.read(Rails.root.join("app/assets/images", folder, image))
+ attachments.inline[image] = File.read(Rails.root.join("app/assets/images", folder, image))
image_tag attachments[image].url, **options
end
end
diff --git a/app/helpers/tree_helper.rb b/app/helpers/tree_helper.rb
index c44a67d3e66..b050f533d77 100644
--- a/app/helpers/tree_helper.rb
+++ b/app/helpers/tree_helper.rb
@@ -4,8 +4,6 @@ module TreeHelper
include BlobHelper
include WebIdeButtonHelper
- FILE_LIMIT = 1_000
-
# Return an image icon depending on the file type and mode
#
# type - String type of the tree item; either 'folder' or 'file'
diff --git a/app/models/ci/build.rb b/app/models/ci/build.rb
index 2ec5817b92a..a9bd890aa4b 100644
--- a/app/models/ci/build.rb
+++ b/app/models/ci/build.rb
@@ -228,7 +228,7 @@ module Ci
end
def with_preloads
- preload(:job_artifacts_archive, :job_artifacts, project: [:namespace])
+ preload(:job_artifacts_archive, :job_artifacts, :tags, project: [:namespace])
end
end
diff --git a/app/models/project_setting.rb b/app/models/project_setting.rb
index aca7eec3382..83ff0702b88 100644
--- a/app/models/project_setting.rb
+++ b/app/models/project_setting.rb
@@ -21,4 +21,4 @@ class ProjectSetting < ApplicationRecord
end
end
-ProjectSetting.prepend_if_ee('EE::ProjectSetting')
+ProjectSetting.prepend_ee_mod
diff --git a/app/services/git/wiki_push_service.rb b/app/services/git/wiki_push_service.rb
index 99659bc8ab2..0905b2d98df 100644
--- a/app/services/git/wiki_push_service.rb
+++ b/app/services/git/wiki_push_service.rb
@@ -16,7 +16,7 @@ module Git
wiki.after_post_receive
process_changes
- perform_housekeeping if Feature.enabled?(:wiki_housekeeping, wiki.container)
+ perform_housekeeping
end
private
diff --git a/app/views/notify/in_product_marketing_email.html.haml b/app/views/notify/in_product_marketing_email.html.haml
index 024cfa97abc..be517516a98 100644
--- a/app/views/notify/in_product_marketing_email.html.haml
+++ b/app/views/notify/in_product_marketing_email.html.haml
@@ -162,7 +162,7 @@
#main-story.mktEditable{ mktoname: "main-story" }
%table{ border: "0", cellpadding: "0", cellspacing: "0", role: "presentation", width: "100%" }
%tr
- %td{ align: "left", style: "padding: 0px;" }
+ %td{ align: "left", style: "padding: 0 20px;" }
= about_link('mailers/in_product_marketing', 'gitlab-logo-gray-rgb.png', 200)
%tr
%td{ "aria-hidden" => "true", height: "30", style: "font-size: 0; line-height: 0;" }
@@ -187,7 +187,7 @@
%p
= in_product_marketing_progress(@track, @series)
%tr{ style: "background-color: #ffffff;" }
- %td{ align: "center", style: "padding:50px 20px 0 20px;" }
+ %td{ align: "center", style: "padding:75px 20px 25px;" }
= about_link('', 'gitlab_logo.png', 80)
%tr{ style: "background-color: #ffffff;" }
%td{ align: "center", style: "padding:0px ;" }
diff --git a/app/views/profiles/keys/index.html.haml b/app/views/profiles/keys/index.html.haml
index 7b7c24f3ac8..80027cdfed0 100644
--- a/app/views/profiles/keys/index.html.haml
+++ b/app/views/profiles/keys/index.html.haml
@@ -11,8 +11,8 @@
%h5.gl-mt-0
= _('Add an SSH key')
%p.profile-settings-content
- - generate_link_url = help_page_path("ssh/README", anchor: 'generating-a-new-ssh-key-pair')
- - existing_link_url = help_page_path("ssh/README", anchor: 'review-existing-ssh-keys')
+ - generate_link_url = help_page_path("ssh/README", anchor: 'generate-an-ssh-key-pair')
+ - existing_link_url = help_page_path("ssh/README", anchor: 'see-if-you-have-an-existing-ssh-key-pair')
- generate_link_start = ''.html_safe % { url: generate_link_url }
- existing_link_start = ''.html_safe % { url: existing_link_url }
= _('To add an SSH key you need to %{generate_link_start}generate one%{link_end} or use an %{existing_link_start}existing key%{link_end}.').html_safe % { generate_link_start: generate_link_start, existing_link_start: existing_link_start, link_end: ''.html_safe }
diff --git a/app/views/projects/_merge_request_merge_checks_settings.html.haml b/app/views/projects/_merge_request_merge_checks_settings.html.haml
index 7a5997bbcfd..b099eb6800e 100644
--- a/app/views/projects/_merge_request_merge_checks_settings.html.haml
+++ b/app/views/projects/_merge_request_merge_checks_settings.html.haml
@@ -24,3 +24,4 @@
= form.check_box :only_allow_merge_if_all_discussions_are_resolved, class: 'form-check-input', data: { qa_selector: 'allow_merge_if_all_discussions_are_resolved_checkbox' }
= form.label :only_allow_merge_if_all_discussions_are_resolved, class: 'form-check-label' do
= s_('ProjectSettings|All discussions must be resolved')
+ = render_if_exists 'projects/merge_request_merge_checks_jira_enforcement', form: form, project: @project
diff --git a/changelogs/unreleased/24488-expose-tag-list.yml b/changelogs/unreleased/24488-expose-tag-list.yml
new file mode 100644
index 00000000000..9c54470b439
--- /dev/null
+++ b/changelogs/unreleased/24488-expose-tag-list.yml
@@ -0,0 +1,5 @@
+---
+title: Add tag_list attribute to the JSON output for Jobs API
+merge_request: 44859
+author: Alon Liszt
+type: added
diff --git a/changelogs/unreleased/283911-tf-alignment.yml b/changelogs/unreleased/283911-tf-alignment.yml
new file mode 100644
index 00000000000..04d8e979586
--- /dev/null
+++ b/changelogs/unreleased/283911-tf-alignment.yml
@@ -0,0 +1,5 @@
+---
+title: Update styles for terraform MR widget
+merge_request: 52627
+author:
+type: changed
diff --git a/changelogs/unreleased/297644-jira-association-requirements-be.yml b/changelogs/unreleased/297644-jira-association-requirements-be.yml
new file mode 100644
index 00000000000..88ec9e2a980
--- /dev/null
+++ b/changelogs/unreleased/297644-jira-association-requirements-be.yml
@@ -0,0 +1,5 @@
+---
+title: Adds jira issue enforcement field
+merge_request: 52896
+author:
+type: added
diff --git a/changelogs/unreleased/299343-fj-enable-housekeeping-for-wikis.yml b/changelogs/unreleased/299343-fj-enable-housekeeping-for-wikis.yml
new file mode 100644
index 00000000000..7ae645820f0
--- /dev/null
+++ b/changelogs/unreleased/299343-fj-enable-housekeeping-for-wikis.yml
@@ -0,0 +1,5 @@
+---
+title: Enable housekeeping for project and group wiki repos
+merge_request: 53011
+author:
+type: added
diff --git a/config/feature_flags/development/wiki_housekeeping.yml b/config/feature_flags/development/query_deploymenys_via_finished_at_in_vsa.yml
similarity index 67%
rename from config/feature_flags/development/wiki_housekeeping.yml
rename to config/feature_flags/development/query_deploymenys_via_finished_at_in_vsa.yml
index aeff94b471b..0f870c09324 100644
--- a/config/feature_flags/development/wiki_housekeeping.yml
+++ b/config/feature_flags/development/query_deploymenys_via_finished_at_in_vsa.yml
@@ -1,8 +1,8 @@
---
-name: wiki_housekeeping
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/51576
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/299343
+name: query_deploymenys_via_finished_at_in_vsa
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/53050
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/300649
milestone: '13.9'
type: development
-group: group::editor
+group: group::optimize
default_enabled: false
diff --git a/db/migrate/20210128101707_add_prevent_merge_without_jira_issue_to_project_settings.rb b/db/migrate/20210128101707_add_prevent_merge_without_jira_issue_to_project_settings.rb
new file mode 100644
index 00000000000..18f186294f1
--- /dev/null
+++ b/db/migrate/20210128101707_add_prevent_merge_without_jira_issue_to_project_settings.rb
@@ -0,0 +1,18 @@
+# frozen_string_literal: true
+
+class AddPreventMergeWithoutJiraIssueToProjectSettings < ActiveRecord::Migration[6.0]
+ include Gitlab::Database::MigrationHelpers
+ DOWNTIME = false
+
+ def up
+ with_lock_retries do
+ add_column :project_settings, :prevent_merge_without_jira_issue, :boolean, null: false, default: false
+ end
+ end
+
+ def down
+ with_lock_retries do
+ remove_column :project_settings, :prevent_merge_without_jira_issue
+ end
+ end
+end
diff --git a/db/schema_migrations/20210128101707 b/db/schema_migrations/20210128101707
new file mode 100644
index 00000000000..f10f080c1df
--- /dev/null
+++ b/db/schema_migrations/20210128101707
@@ -0,0 +1 @@
+ae84fa35fcc5a0780d86887294a32e250d2ac13dcf607750f834df5828e5bece
\ No newline at end of file
diff --git a/db/structure.sql b/db/structure.sql
index 8c1ed479c69..5211776e17f 100644
--- a/db/structure.sql
+++ b/db/structure.sql
@@ -16064,6 +16064,7 @@ CREATE TABLE project_settings (
has_confluence boolean DEFAULT false NOT NULL,
has_vulnerabilities boolean DEFAULT false NOT NULL,
allow_editing_commit_messages boolean DEFAULT false NOT NULL,
+ prevent_merge_without_jira_issue boolean DEFAULT false NOT NULL,
CONSTRAINT check_bde223416c CHECK ((show_default_award_emojis IS NOT NULL))
);
diff --git a/doc/README.md b/doc/README.md
index 4202da762d1..7a32c317085 100644
--- a/doc/README.md
+++ b/doc/README.md
@@ -68,7 +68,7 @@ We have the following documentation to rapidly uplift your GitLab knowledge:
|:--------------------------------------------------------------------------------------------------|:------------|
| [GitLab basics guides](gitlab-basics/README.md) | Start working on the command line and with GitLab. |
| [GitLab workflow overview](https://about.gitlab.com/blog/2016/10/25/gitlab-workflow-an-overview/) | Enhance your workflow with the best of GitLab Workflow. |
-| [Get started with GitLab CI/CD](ci/quick_start/README.md) | Quickly implement GitLab CI/CD. |
+| [Get started with GitLab CI/CD](ci/quick_start/index.md) | Quickly implement GitLab CI/CD. |
| [Auto DevOps](topics/autodevops/index.md) | Learn more about Auto DevOps in GitLab. |
| [GitLab Markdown](user/markdown.md) | Advanced formatting system (GitLab Flavored Markdown). |
diff --git a/doc/api/graphql/index.md b/doc/api/graphql/index.md
index a97d892dbc4..7a68b1cdf16 100644
--- a/doc/api/graphql/index.md
+++ b/doc/api/graphql/index.md
@@ -48,7 +48,7 @@ libraries](https://graphql.org/code/#graphql-clients) to consume the
API and avoid manual parsing.
Since there's no fixed endpoints and data model, new abilities can be
-added to the API without creating breaking changes. This allows us to
+added to the API without creating [breaking changes](../../development/contributing/#breaking-changes). This allows us to
have a versionless API as described in [the GraphQL
documentation](https://graphql.org/learn/best-practices/#versioning).
diff --git a/doc/api/graphql/reference/gitlab_schema.graphql b/doc/api/graphql/reference/gitlab_schema.graphql
index f842cc2ee10..fa4b84eb3b7 100644
--- a/doc/api/graphql/reference/gitlab_schema.graphql
+++ b/doc/api/graphql/reference/gitlab_schema.graphql
@@ -5737,7 +5737,7 @@ type DastProfileCreatePayload {
"""
The URL of the pipeline that was created. Requires `runAfterCreate` to be set to `true`.
"""
- pipelineUrl: String!
+ pipelineUrl: String
}
"""
diff --git a/doc/api/graphql/reference/gitlab_schema.json b/doc/api/graphql/reference/gitlab_schema.json
index f42faa8fd4f..1101990e0fa 100644
--- a/doc/api/graphql/reference/gitlab_schema.json
+++ b/doc/api/graphql/reference/gitlab_schema.json
@@ -15668,13 +15668,9 @@
],
"type": {
- "kind": "NON_NULL",
- "name": null,
- "ofType": {
- "kind": "SCALAR",
- "name": "String",
- "ofType": null
- }
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
},
"isDeprecated": false,
"deprecationReason": null
diff --git a/doc/api/graphql/reference/index.md b/doc/api/graphql/reference/index.md
index df78b72d4dc..95ed4508ba4 100644
--- a/doc/api/graphql/reference/index.md
+++ b/doc/api/graphql/reference/index.md
@@ -914,7 +914,7 @@ Autogenerated return type of DastProfileCreate.
| `clientMutationId` | String | A unique identifier for the client performing the mutation. |
| `dastProfile` | DastProfile | The created profile. |
| `errors` | String! => Array | Errors encountered during execution of the mutation. |
-| `pipelineUrl` | String! | The URL of the pipeline that was created. Requires `runAfterCreate` to be set to `true`. |
+| `pipelineUrl` | String | The URL of the pipeline that was created. Requires `runAfterCreate` to be set to `true`. |
### DastScannerProfile
diff --git a/doc/api/jobs.md b/doc/api/jobs.md
index b7b742ebe66..2c935b6e288 100644
--- a/doc/api/jobs.md
+++ b/doc/api/jobs.md
@@ -54,6 +54,9 @@ Example of response
{"file_type": "junit", "size": 750, "filename": "junit.xml.gz", "file_format": "gzip"}
],
"artifacts_expire_at": "2016-01-23T17:54:27.895Z",
+ "tag_list": [
+ "docker runner", "ubuntu18"
+ ],
"id": 7,
"name": "teaspoon",
"pipeline": {
@@ -104,6 +107,9 @@ Example of response
"finished_at": "2015-12-24T17:54:24.921Z",
"duration": 0.192,
"artifacts_expire_at": "2016-01-23T17:54:24.921Z",
+ "tag_list": [
+ "docker runner", "win10-2004"
+ ],
"id": 6,
"name": "rspec:other",
"pipeline": {
@@ -179,6 +185,9 @@ Example of response
"finished_at": "2015-12-24T17:54:24.921Z",
"duration": 0.192,
"artifacts_expire_at": "2016-01-23T17:54:24.921Z",
+ "tag_list": [
+ "docker runner", "ubuntu18"
+ ],
"id": 6,
"name": "rspec:other",
"pipeline": {
@@ -239,6 +248,9 @@ Example of response
{"file_type": "junit", "size": 750, "filename": "junit.xml.gz", "file_format": "gzip"}
],
"artifacts_expire_at": "2016-01-23T17:54:27.895Z",
+ "tag_list": [
+ "docker runner", "ubuntu18"
+ ],
"id": 7,
"name": "teaspoon",
"pipeline": {
@@ -399,6 +411,9 @@ Example of response
"finished_at": "2015-12-24T17:54:31.198Z",
"duration": 0.465,
"artifacts_expire_at": "2016-01-23T17:54:31.198Z",
+ "tag_list": [
+ "docker runner", "macos-10.15"
+ ],
"id": 8,
"name": "rubocop",
"pipeline": {
diff --git a/doc/ci/README.md b/doc/ci/README.md
index dcac628eab1..4ad9af00e4f 100644
--- a/doc/ci/README.md
+++ b/doc/ci/README.md
@@ -55,7 +55,7 @@ at the repository's root. This file creates a [pipeline](pipelines/index.md), wh
To get started with GitLab CI/CD, we recommend you read through
the following documents:
-- [Get started with GitLab CI/CD](quick_start/README.md).
+- [Get started with GitLab CI/CD](quick_start/index.md).
- [Fundamental pipeline architectures](pipelines/pipeline_architectures.md).
- [GitLab CI/CD basic workflow](introduction/index.md#basic-cicd-workflow).
- [Step-by-step guide for writing `.gitlab-ci.yml` for the first time](../user/project/pages/getting_started/pages_from_scratch.md).
@@ -75,7 +75,7 @@ to your needs:
While building your `.gitlab-ci.yml`, you can use the [CI/CD configuration visualization](pipeline_editor/index.md#visualize-ci-configuration) to facilitate your writing experience.
-For a broader overview, see the [CI/CD getting started](quick_start/README.md) guide.
+For a broader overview, see the [CI/CD getting started](quick_start/index.md) guide.
After you're familiar with how GitLab CI/CD works, see the
[`.gitlab-ci.yml` full reference](yaml/README.md)
@@ -107,7 +107,7 @@ GitLab CI/CD supports numerous configuration options:
| [Schedule pipelines](pipelines/schedules.md) | Schedule pipelines to run as often as you need. |
| [Custom path for `.gitlab-ci.yml`](pipelines/settings.md#custom-cicd-configuration-path) | Define a custom path for the CI/CD configuration file. |
| [Git submodules for CI/CD](git_submodules.md) | Configure jobs for using Git submodules. |
-| [SSH keys for CI/CD](ssh_keys/README.md) | Using SSH keys in your CI pipelines. |
+| [SSH keys for CI/CD](ssh_keys/index.md) | Using SSH keys in your CI pipelines. |
| [Pipeline triggers](triggers/README.md) | Trigger pipelines through the API. |
| [Pipelines for Merge Requests](merge_request_pipelines/index.md) | Design a pipeline structure for running a pipeline in merge requests. |
| [Integrate with Kubernetes clusters](../user/project/clusters/index.md) | Connect your project to Google Kubernetes Engine (GKE) or an existing Kubernetes cluster. |
@@ -126,12 +126,12 @@ Its feature set is listed on the table below according to DevOps stages.
|:------------------------------------------------------------------------------------------------|:-------------------------------------------------------------------------------------------------------------------------------|
| **Configure** | |
| [Auto DevOps](../topics/autodevops/index.md) | Set up your app's entire lifecycle. |
-| [ChatOps](chatops/README.md) | Trigger CI jobs from chat, with results sent back to the channel. |
+| [ChatOps](chatops/index.md) | Trigger CI jobs from chat, with results sent back to the channel. |
|-------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------|
| **Verify** | |
| [Browser Performance Testing](../user/project/merge_requests/browser_performance_testing.md) | Quickly determine the browser performance impact of pending code changes. |
| [Load Performance Testing](../user/project/merge_requests/load_performance_testing.md) | Quickly determine the server performance impact of pending code changes. |
-| [CI services](services/README.md) | Link Docker containers with your base image. |
+| [CI services](services/index.md) | Link Docker containers with your base image. |
| [Code Quality](../user/project/merge_requests/code_quality.md) | Analyze your source code quality. |
| [GitLab CI/CD for external repositories](ci_cd_for_external_repos/index.md) **(PREMIUM)** | Get the benefits of GitLab CI/CD combined with repositories in GitHub and Bitbucket Cloud. |
| [Interactive Web Terminals](interactive_web_terminal/index.md) **(FREE SELF)** | Open an interactive web terminal to debug the running jobs. |
diff --git a/doc/ci/chatops/README.md b/doc/ci/chatops/README.md
index 4ec921b4447..c94d6e3ea80 100644
--- a/doc/ci/chatops/README.md
+++ b/doc/ci/chatops/README.md
@@ -1,116 +1,8 @@
---
-stage: Configure
-group: Configure
-info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
-type: index, concepts, howto
+redirect_to: 'index.md'
---
-# GitLab ChatOps **(FREE)**
+This document was moved to [another location](index.md).
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/4466) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 10.6.
-> - [Moved](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/24780) to [GitLab Free](https://about.gitlab.com/pricing/) in 11.9.
-
-GitLab ChatOps provides a method to interact with CI/CD jobs through chat services
-like Slack. Many organizations' discussion, collaboration, and troubleshooting takes
-place in chat services. Having a method to run CI/CD jobs with output
-posted back to the channel can significantly augment your team's workflow.
-
-## How GitLab ChatOps works
-
-GitLab ChatOps is built upon [GitLab CI/CD](../README.md) and
-[Slack Slash Commands](../../user/project/integrations/slack_slash_commands.md).
-ChatOps provides a `run` action for [slash commands](../../integration/slash_commands.md)
-with the following arguments:
-
-- A `` to execute.
-- The ``.
-
-ChatOps passes the following [CI/CD variables](../variables/README.md#predefined-environment-variables)
-to the job:
-
-- `CHAT_INPUT` contains any additional arguments.
-- `CHAT_CHANNEL` is set to the name of channel the action was triggered in.
-
-When executed, ChatOps looks up the specified job name and attempts to match it
-to a corresponding job in [`.gitlab-ci.yml`](../yaml/README.md). If a matching job
-is found on `master`, a pipeline containing only that job is scheduled. After the
-job completes:
-
-- If the job completes in *less than 30 minutes*, the ChatOps sends the job's output to Slack.
-- If the job completes in *more than 30 minutes*, the job must use the
- [Slack API](https://api.slack.com/) to send data to the channel.
-
-To use the `run` command, you must have
-[Developer access or above](../../user/permissions.md#project-members-permissions).
-If a job shouldn't be able to be triggered from chat, you can set the job to `except: [chat]`.
-
-## Best practices for ChatOps CI jobs
-
-Since ChatOps is built upon GitLab CI/CD, the job has all the same features and
-functions available. Consider these best practices when creating ChatOps jobs:
-
-- GitLab strongly recommends you set `only: [chat]` so the job does not run as part
- of the standard CI pipeline.
-- If the job is set to `when: manual`, ChatOps creates the pipeline, but the job waits to be started.
-- ChatOps provides limited support for access control. If the user triggering the
- slash command has [Developer access or above](../../user/permissions.md#project-members-permissions)
- in the project, the job runs. The job itself can use existing
- [CI/CD variables](../variables/README.md#predefined-environment-variables) like
- `GITLAB_USER_ID` to perform additional rights validation, but
- these variables can be [overridden](../variables/README.md#priority-of-environment-variables).
-
-### Controlling the ChatOps reply
-
-The output for jobs with a single command is sent to the channel as a reply. For
-example, the chat reply of the following job is `Hello World` in the channel:
-
-```yaml
-hello-world:
- stage: chatops
- only: [chat]
- script:
- - echo "Hello World"
-```
-
-Jobs that contain multiple commands (or `before_script`) return additional
-content in the chat reply. In these cases, both the commands and their output are
-included, with the commands wrapped in ANSI color codes.
-
-To selectively reply with the output of one command, its output must be bounded by
-the `chat_reply` section. For example, the following job lists the files in the
-current directory:
-
-```yaml
-ls:
- stage: chatops
- only: [chat]
- script:
- - echo "This command will not be shown."
- - echo -e "section_start:$( date +%s ):chat_reply\r\033[0K\n$( ls -la )\nsection_end:$( date +%s ):chat_reply\r\033[0K"
-```
-
-## GitLab ChatOps examples
-
-The GitLab.com team created a repository of [common ChatOps scripts](https://gitlab.com/gitlab-com/chatops)
-they use to interact with our Production instance of GitLab. Administrators of
-other GitLab instances may find them useful. They can serve as inspiration for ChatOps
-scripts you can write to interact with your own applications.
-
-## GitLab ChatOps icon
-
-The [official GitLab ChatOps icon](img/gitlab-chatops-icon.png) is available for download.
-You can find and download the official GitLab ChatOps icon here.
-
-![GitLab ChatOps bot icon](img/gitlab-chatops-icon-small.png)
-
-
+
+
diff --git a/doc/ci/chatops/index.md b/doc/ci/chatops/index.md
new file mode 100644
index 00000000000..4ec921b4447
--- /dev/null
+++ b/doc/ci/chatops/index.md
@@ -0,0 +1,116 @@
+---
+stage: Configure
+group: Configure
+info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
+type: index, concepts, howto
+---
+
+# GitLab ChatOps **(FREE)**
+
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/4466) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 10.6.
+> - [Moved](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/24780) to [GitLab Free](https://about.gitlab.com/pricing/) in 11.9.
+
+GitLab ChatOps provides a method to interact with CI/CD jobs through chat services
+like Slack. Many organizations' discussion, collaboration, and troubleshooting takes
+place in chat services. Having a method to run CI/CD jobs with output
+posted back to the channel can significantly augment your team's workflow.
+
+## How GitLab ChatOps works
+
+GitLab ChatOps is built upon [GitLab CI/CD](../README.md) and
+[Slack Slash Commands](../../user/project/integrations/slack_slash_commands.md).
+ChatOps provides a `run` action for [slash commands](../../integration/slash_commands.md)
+with the following arguments:
+
+- A `` to execute.
+- The ``.
+
+ChatOps passes the following [CI/CD variables](../variables/README.md#predefined-environment-variables)
+to the job:
+
+- `CHAT_INPUT` contains any additional arguments.
+- `CHAT_CHANNEL` is set to the name of channel the action was triggered in.
+
+When executed, ChatOps looks up the specified job name and attempts to match it
+to a corresponding job in [`.gitlab-ci.yml`](../yaml/README.md). If a matching job
+is found on `master`, a pipeline containing only that job is scheduled. After the
+job completes:
+
+- If the job completes in *less than 30 minutes*, the ChatOps sends the job's output to Slack.
+- If the job completes in *more than 30 minutes*, the job must use the
+ [Slack API](https://api.slack.com/) to send data to the channel.
+
+To use the `run` command, you must have
+[Developer access or above](../../user/permissions.md#project-members-permissions).
+If a job shouldn't be able to be triggered from chat, you can set the job to `except: [chat]`.
+
+## Best practices for ChatOps CI jobs
+
+Since ChatOps is built upon GitLab CI/CD, the job has all the same features and
+functions available. Consider these best practices when creating ChatOps jobs:
+
+- GitLab strongly recommends you set `only: [chat]` so the job does not run as part
+ of the standard CI pipeline.
+- If the job is set to `when: manual`, ChatOps creates the pipeline, but the job waits to be started.
+- ChatOps provides limited support for access control. If the user triggering the
+ slash command has [Developer access or above](../../user/permissions.md#project-members-permissions)
+ in the project, the job runs. The job itself can use existing
+ [CI/CD variables](../variables/README.md#predefined-environment-variables) like
+ `GITLAB_USER_ID` to perform additional rights validation, but
+ these variables can be [overridden](../variables/README.md#priority-of-environment-variables).
+
+### Controlling the ChatOps reply
+
+The output for jobs with a single command is sent to the channel as a reply. For
+example, the chat reply of the following job is `Hello World` in the channel:
+
+```yaml
+hello-world:
+ stage: chatops
+ only: [chat]
+ script:
+ - echo "Hello World"
+```
+
+Jobs that contain multiple commands (or `before_script`) return additional
+content in the chat reply. In these cases, both the commands and their output are
+included, with the commands wrapped in ANSI color codes.
+
+To selectively reply with the output of one command, its output must be bounded by
+the `chat_reply` section. For example, the following job lists the files in the
+current directory:
+
+```yaml
+ls:
+ stage: chatops
+ only: [chat]
+ script:
+ - echo "This command will not be shown."
+ - echo -e "section_start:$( date +%s ):chat_reply\r\033[0K\n$( ls -la )\nsection_end:$( date +%s ):chat_reply\r\033[0K"
+```
+
+## GitLab ChatOps examples
+
+The GitLab.com team created a repository of [common ChatOps scripts](https://gitlab.com/gitlab-com/chatops)
+they use to interact with our Production instance of GitLab. Administrators of
+other GitLab instances may find them useful. They can serve as inspiration for ChatOps
+scripts you can write to interact with your own applications.
+
+## GitLab ChatOps icon
+
+The [official GitLab ChatOps icon](img/gitlab-chatops-icon.png) is available for download.
+You can find and download the official GitLab ChatOps icon here.
+
+![GitLab ChatOps bot icon](img/gitlab-chatops-icon-small.png)
+
+
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 8e3d609b5dc..bef3b54bf4e 100644
--- a/doc/ci/ci_cd_for_external_repos/github_integration.md
+++ b/doc/ci/ci_cd_for_external_repos/github_integration.md
@@ -41,7 +41,7 @@ repositories:
1. Paste the token into the **Personal access token** field and click **List
Repositories**. Click **Connect** to select the repository.
-1. In GitHub, add a `.gitlab-ci.yml` to [configure GitLab CI/CD](../quick_start/README.md).
+1. In GitHub, add a `.gitlab-ci.yml` to [configure GitLab CI/CD](../quick_start/index.md).
GitLab:
diff --git a/doc/ci/docker/README.md b/doc/ci/docker/README.md
index 18a9d63b694..c94d6e3ea80 100644
--- a/doc/ci/docker/README.md
+++ b/doc/ci/docker/README.md
@@ -1,18 +1,8 @@
---
-stage: Verify
-group: Continuous Integration
-info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
-comments: false
-type: index
+redirect_to: 'index.md'
---
-# Docker integration
+This document was moved to [another location](index.md).
-GitLab CI/CD can be combined with [Docker](https://www.docker.com) to enable
-integration between the two.
-
-The following documentation is available for using GitLab CI/CD with Docker:
-
-- [Building Docker images with GitLab CI/CD](using_docker_build.md).
-- [Using Docker images](using_docker_images.md).
-- [Building images with kaniko and GitLab CI/CD](using_kaniko.md).
+
+
diff --git a/doc/ci/docker/index.md b/doc/ci/docker/index.md
new file mode 100644
index 00000000000..18a9d63b694
--- /dev/null
+++ b/doc/ci/docker/index.md
@@ -0,0 +1,18 @@
+---
+stage: Verify
+group: Continuous Integration
+info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
+comments: false
+type: index
+---
+
+# Docker integration
+
+GitLab CI/CD can be combined with [Docker](https://www.docker.com) to enable
+integration between the two.
+
+The following documentation is available for using GitLab CI/CD with Docker:
+
+- [Building Docker images with GitLab CI/CD](using_docker_build.md).
+- [Using Docker images](using_docker_images.md).
+- [Building images with kaniko and GitLab CI/CD](using_kaniko.md).
diff --git a/doc/ci/docker/using_docker_images.md b/doc/ci/docker/using_docker_images.md
index 630e106b72c..4025d0d928e 100644
--- a/doc/ci/docker/using_docker_images.md
+++ b/doc/ci/docker/using_docker_images.md
@@ -91,7 +91,7 @@ Services inherit the same DNS servers, search domains, and additional hosts as
the CI container itself.
You can see some widely used services examples in the relevant documentation of
-[CI services examples](../services/README.md).
+[CI services examples](../services/index.md).
### How services are linked to the job
diff --git a/doc/ci/enable_or_disable_ci.md b/doc/ci/enable_or_disable_ci.md
index f59e32fb46d..72fd9833df1 100644
--- a/doc/ci/enable_or_disable_ci.md
+++ b/doc/ci/enable_or_disable_ci.md
@@ -13,7 +13,7 @@ To effectively use GitLab CI/CD, you need:
of your project.
- A [runner](runners/README.md) properly set up.
-You can read our [quick start guide](quick_start/README.md) to get you started.
+You can read our [quick start guide](quick_start/index.md) to get you started.
If you are using an external CI/CD server like Jenkins or Drone CI, it is advised
to disable GitLab CI/CD in order to not have any conflicts with the commits status
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 c6ddeefb916..dbbc751acf9 100644
--- a/doc/ci/examples/laravel_with_gitlab_and_envoy/index.md
+++ b/doc/ci/examples/laravel_with_gitlab_and_envoy/index.md
@@ -544,7 +544,7 @@ services:
...
```
-If you wish to test your app with different PHP versions and [database management systems](../../services/README.md), you can define different `image` and `services` keywords for each test job.
+If you wish to test your app with different PHP versions and [database management systems](../../services/index.md), you can define different `image` and `services` keywords for each test job.
#### Variables
@@ -589,7 +589,7 @@ unit_test:
#### Deploy to production
The job `deploy_production` will deploy the app to the production server.
-To deploy our app with Envoy, we had to set up the `$SSH_PRIVATE_KEY` variable as an [SSH private key](../../ssh_keys/README.md#ssh-keys-when-using-the-docker-executor).
+To deploy our app with Envoy, we had to set up the `$SSH_PRIVATE_KEY` variable as an [SSH private key](../../ssh_keys/index.md#ssh-keys-when-using-the-docker-executor).
If the SSH keys have added successfully, we can run Envoy.
As mentioned before, GitLab supports [Continuous Delivery](https://about.gitlab.com/blog/2016/08/05/continuous-integration-delivery-and-deployment-with-gitlab/#continuous-delivery) methods as well.
diff --git a/doc/ci/examples/php.md b/doc/ci/examples/php.md
index b61943f0c32..53014585f2e 100644
--- a/doc/ci/examples/php.md
+++ b/doc/ci/examples/php.md
@@ -241,7 +241,7 @@ before_script:
## 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) to be able to clone it.
+the [SSH keys](../ssh_keys/index.md) to be able to clone it.
## Use databases or other services
@@ -250,7 +250,7 @@ run. If you're using the Docker executor, you can leverage Docker's ability to
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)
+This functionality is covered in [the CI services](../services/index.md)
documentation.
## Testing things locally
diff --git a/doc/ci/git_submodules.md b/doc/ci/git_submodules.md
index fb42ed64e78..d9a40c1feb6 100644
--- a/doc/ci/git_submodules.md
+++ b/doc/ci/git_submodules.md
@@ -13,7 +13,7 @@ type: reference
> are encouraged to upgrade your GitLab instance if you haven't done already.
> If you are **not** using GitLab 8.12 or higher, you would need to work your way
> around submodules in order to access the sources of e.g., `gitlab.com/group/project`
-> with the use of [SSH keys](ssh_keys/README.md).
+> with the use of [SSH keys](ssh_keys/index.md).
> - With GitLab 8.12 onward, your permissions are used to evaluate what a CI job
> can access. More information about how this system works can be found in the
> [Jobs permissions model](../user/permissions.md#job-permissions).
diff --git a/doc/ci/migration/circleci.md b/doc/ci/migration/circleci.md
index 73219bb8ed7..4c62e2a645e 100644
--- a/doc/ci/migration/circleci.md
+++ b/doc/ci/migration/circleci.md
@@ -15,7 +15,7 @@ comparison to see what's different.
We have collected several resources that you may find useful before starting to migrate.
-The [Quick Start Guide](../quick_start/README.md) is a good overview of how GitLab CI/CD works. You may also be interested in [Auto DevOps](../../topics/autodevops/index.md) which can be used to build, test, and deploy your applications with little to no configuration needed at all.
+The [Quick Start Guide](../quick_start/index.md) is a good overview of how GitLab CI/CD works. You may also be interested in [Auto DevOps](../../topics/autodevops/index.md) which can be used to build, test, and deploy your applications with little to no configuration needed at all.
For advanced CI/CD teams, [custom project templates](../../user/admin_area/custom_project_templates.md) can enable the reuse of pipeline configurations.
diff --git a/doc/ci/migration/jenkins.md b/doc/ci/migration/jenkins.md
index 8392bfa50fa..1b3cea6c755 100644
--- a/doc/ci/migration/jenkins.md
+++ b/doc/ci/migration/jenkins.md
@@ -15,11 +15,11 @@ before diving in. Think of this page as a "GitLab CI/CD for Jenkins Users" guide
The following list of recommended steps was created after observing organizations
that were able to quickly complete this migration:
-1. Start by reading the GitLab CI/CD [Quick Start Guide](../quick_start/README.md) and [important product differences](#important-product-differences).
+1. Start by reading the GitLab CI/CD [Quick Start Guide](../quick_start/index.md) and [important product differences](#important-product-differences).
1. Learn the importance of [managing the organizational transition](#managing-the-organizational-transition).
1. [Add runners](../runners/README.md) to your GitLab instance.
1. Educate and enable your developers to independently perform the following steps in their projects:
- 1. Review the [Quick Start Guide](../quick_start/README.md) and [Pipeline Configuration Reference](../yaml/README.md).
+ 1. Review the [Quick Start Guide](../quick_start/index.md) and [Pipeline Configuration Reference](../yaml/README.md).
1. Use the [Jenkins Wrapper](#jenkinsfile-wrapper) to temporarily maintain fragile Jenkins jobs.
1. Migrate the build and CI jobs and configure them to show results directly in your merge requests. They can use [Auto DevOps](../../topics/autodevops/index.md) as a starting point, and [customize](../../topics/autodevops/customize.md) or [decompose](../../topics/autodevops/customize.md#using-components-of-auto-devops) the configuration as needed.
1. Add [Review Apps](../review_apps/index.md).
@@ -79,7 +79,7 @@ There are some high level differences between the products worth mentioning:
- from the [GitLab UI](../pipelines/index.md#run-a-pipeline-manually)
- by [API call](../triggers/README.md)
- by [webhook](../triggers/README.md#triggering-a-pipeline-from-a-webhook)
- - by [ChatOps](../chatops/README.md)
+ - by [ChatOps](../chatops/index.md)
- You can control which jobs run in which cases, depending on how they are triggered,
with the [`rules` syntax](../yaml/README.md#rules).
diff --git a/doc/ci/pipeline_editor/index.md b/doc/ci/pipeline_editor/index.md
index 4ddaa16d7c5..bb61c22d638 100644
--- a/doc/ci/pipeline_editor/index.md
+++ b/doc/ci/pipeline_editor/index.md
@@ -28,7 +28,7 @@ From the pipeline editor page you can:
- [Commit](#commit-changes-to-ci-configuration) the changes to a specific branch.
NOTE:
-You must already have [a `.gitlab-ci.yml` file](../quick_start/README.md#create-a-gitlab-ciyml-file)
+You must already have [a `.gitlab-ci.yml` file](../quick_start/index.md#create-a-gitlab-ciyml-file)
on the default branch (usually "master") of your project to use the editor.
## Validate CI configuration
diff --git a/doc/ci/pipelines/pipeline_efficiency.md b/doc/ci/pipelines/pipeline_efficiency.md
index a2df228e3a2..faebf40462e 100644
--- a/doc/ci/pipelines/pipeline_efficiency.md
+++ b/doc/ci/pipelines/pipeline_efficiency.md
@@ -20,7 +20,7 @@ to use pipeline features that improve efficiency right away, and get a faster so
development lifecycle earlier.
First ensure you are familiar with [GitLab CI/CD fundamentals](../introduction/index.md)
-and understand the [quick start guide](../quick_start/README.md).
+and understand the [quick start guide](../quick_start/index.md).
## Identify bottlenecks and common failures
@@ -235,7 +235,7 @@ Methods to reduce Docker image size:
to analyze and shrink images.
To simplify Docker image management, you can create a dedicated group for managing
-[Docker images](../docker/README.md) and test, build and publish them with CI/CD pipelines.
+[Docker images](../docker/index.md) and test, build and publish them with CI/CD pipelines.
## Test, document, and learn
diff --git a/doc/ci/quick_start/README.md b/doc/ci/quick_start/README.md
index e9c85353db3..c94d6e3ea80 100644
--- a/doc/ci/quick_start/README.md
+++ b/doc/ci/quick_start/README.md
@@ -1,157 +1,8 @@
---
-stage: Verify
-group: Continuous Integration
-info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
-type: reference
+redirect_to: 'index.md'
---
-# Get started with GitLab CI/CD
+This document was moved to [another location](index.md).
-Use this document to get started with
-GitLab [continuous integration](https://about.gitlab.com/stages-devops-lifecycle/continuous-integration/).
-
-Before you start, make sure you have:
-
-- A project in GitLab that you would like to use CI/CD for.
-- Maintainer or owner access for the project.
-
-If you are migrating from another CI/CD tool, view this documentation:
-
-- [Migrate from CircleCI](../migration/circleci.md).
-- [Migrate from Jenkins](../migration/jenkins.md).
-
-## CI/CD process overview
-
-To use GitLab CI/CD:
-
-1. [Ensure you have runners available](#ensure-you-have-runners-available) to run your jobs.
- If you don't have a runner, [install GitLab Runner](https://docs.gitlab.com/runner/install/)
- and [register a runner](https://docs.gitlab.com/runner/register/) for your instance, project, or group.
-1. [Create a `.gitlab-ci.yml` file](#create-a-gitlab-ciyml-file)
- at the root of your repository. This file is where you define your CI/CD jobs.
-
-When you commit the file to your repository, the runner runs your jobs.
-The job results [are displayed in a pipeline](#view-the-status-of-your-pipeline-and-jobs).
-
-### Ensure you have runners available
-
-In GitLab, runners are agents that run your CI/CD jobs.
-
-You might already have runners available for your project, including
-[shared runners](../runners/README.md#shared-runners), which are
-available to all projects in your GitLab instance.
-
-To view available runners:
-
-- Go to **Settings > CI/CD** and expand **Runners**.
-
-As long as you have at least one runner that's active, with a green circle next to it,
-you have a runner available to process your jobs.
-
-If no runners are listed on the **Runners** page in the UI, you or an administrator
-must [install GitLab Runner](https://docs.gitlab.com/runner/install/) and
-[register](https://docs.gitlab.com/runner/register/) at least one runner.
-
-If you are testing CI/CD, you can install GitLab Runner and register runners on your local machine.
-When your CI/CD jobs run, they run on your local machine.
-
-### Create a `.gitlab-ci.yml` file
-
-The `.gitlab-ci.yml` file is a [YAML](https://en.wikipedia.org/wiki/YAML) file where
-you configure specific instructions for GitLab CI/CD.
-
-In this file, you define:
-
-- The structure and order of jobs that the runner should execute.
-- The decisions the runner should make when specific conditions are encountered.
-
-For example, you might want to run a suite of tests when you commit to
-any branch except `master`. When you commit to `master`, you want
-to run the same suite, but also publish your application.
-
-All of this is defined in the `.gitlab-ci.yml` file.
-
-To create a `.gitlab-ci.yml` file:
-
-1. Go to **Project overview > Details**.
-1. Above the file list, select the branch you want to commit to,
- click the plus icon, then select **New file**:
-
- ![New file](img/new_file_v13_6.png)
-
-1. For the **Filename**, type `.gitlab-ci.yml` and in the larger window,
- paste this sample code:
-
- ```yaml
- build-job:
- stage: build
- script:
- - echo "Hello, $GITLAB_USER_LOGIN!"
-
- test-job1:
- stage: test
- script:
- - echo "This job tests something"
-
- test-job2:
- stage: test
- script:
- - echo "This job tests something, but takes more time than test-job1."
- - echo "After the echo commands complete, it runs the sleep command for 20 seconds"
- - echo "which simulates a test that runs 20 seconds longer than test-job1"
- - sleep 20
-
- deploy-prod:
- stage: deploy
- script:
- - echo "This job deploys something from the $CI_COMMIT_BRANCH branch."
- ```
-
- `$GITLAB_USER_LOGIN` and `$CI_COMMIT_BRANCH` are
- [predefined variables](../variables/predefined_variables.md)
- that populate when the job runs.
-
-1. Click **Commit changes**.
-
-The pipeline starts when the commit is committed.
-
-#### `.gitlab-ci.yml` tips
-
-- If you want the runner to use a Docker image to run the jobs, edit the `.gitlab-ci.yml` file
- to include your image name:
-
- ```yaml
- default:
- image: ruby:2.7.2
- ```
-
- This command tells the runner to use a Ruby image from Docker Hub.
-
-- To validate your `.gitlab-ci.yml` file, use the
- [CI Lint tool](../lint.md), which is available in every project.
-- You can also use [CI/CD configuration visualization](../pipeline_editor/index.md#visualize-ci-configuration) to
- view a graphical representation of your `.gitlab-ci.yml` file.
-- For the complete `.gitlab-ci.yml` syntax, see
- [the `.gitlab-ci.yml` reference topic](../yaml/README.md).
-
-### View the status of your pipeline and jobs
-
-When you committed your changes, a pipeline started.
-
-To view your pipeline:
-
-- Go **CI/CD > Pipelines**.
-
- A pipeline with three stages should be displayed:
-
- ![Three stages](img/three_stages_v13_6.png)
-
-- To view a visual representation of your pipeline, click the pipeline ID.
-
- ![Pipeline graph](img/pipeline_graph_v13_6.png)
-
-- To view details of a job, click the job name, for example, `deploy-prod`.
-
- ![Job details](img/job_details_v13_6.png)
-
-If the job status is `stuck`, check to ensure a runner is probably configured for the project.
+
+
diff --git a/doc/ci/quick_start/index.md b/doc/ci/quick_start/index.md
new file mode 100644
index 00000000000..e9c85353db3
--- /dev/null
+++ b/doc/ci/quick_start/index.md
@@ -0,0 +1,157 @@
+---
+stage: Verify
+group: Continuous Integration
+info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
+type: reference
+---
+
+# Get started with GitLab CI/CD
+
+Use this document to get started with
+GitLab [continuous integration](https://about.gitlab.com/stages-devops-lifecycle/continuous-integration/).
+
+Before you start, make sure you have:
+
+- A project in GitLab that you would like to use CI/CD for.
+- Maintainer or owner access for the project.
+
+If you are migrating from another CI/CD tool, view this documentation:
+
+- [Migrate from CircleCI](../migration/circleci.md).
+- [Migrate from Jenkins](../migration/jenkins.md).
+
+## CI/CD process overview
+
+To use GitLab CI/CD:
+
+1. [Ensure you have runners available](#ensure-you-have-runners-available) to run your jobs.
+ If you don't have a runner, [install GitLab Runner](https://docs.gitlab.com/runner/install/)
+ and [register a runner](https://docs.gitlab.com/runner/register/) for your instance, project, or group.
+1. [Create a `.gitlab-ci.yml` file](#create-a-gitlab-ciyml-file)
+ at the root of your repository. This file is where you define your CI/CD jobs.
+
+When you commit the file to your repository, the runner runs your jobs.
+The job results [are displayed in a pipeline](#view-the-status-of-your-pipeline-and-jobs).
+
+### Ensure you have runners available
+
+In GitLab, runners are agents that run your CI/CD jobs.
+
+You might already have runners available for your project, including
+[shared runners](../runners/README.md#shared-runners), which are
+available to all projects in your GitLab instance.
+
+To view available runners:
+
+- Go to **Settings > CI/CD** and expand **Runners**.
+
+As long as you have at least one runner that's active, with a green circle next to it,
+you have a runner available to process your jobs.
+
+If no runners are listed on the **Runners** page in the UI, you or an administrator
+must [install GitLab Runner](https://docs.gitlab.com/runner/install/) and
+[register](https://docs.gitlab.com/runner/register/) at least one runner.
+
+If you are testing CI/CD, you can install GitLab Runner and register runners on your local machine.
+When your CI/CD jobs run, they run on your local machine.
+
+### Create a `.gitlab-ci.yml` file
+
+The `.gitlab-ci.yml` file is a [YAML](https://en.wikipedia.org/wiki/YAML) file where
+you configure specific instructions for GitLab CI/CD.
+
+In this file, you define:
+
+- The structure and order of jobs that the runner should execute.
+- The decisions the runner should make when specific conditions are encountered.
+
+For example, you might want to run a suite of tests when you commit to
+any branch except `master`. When you commit to `master`, you want
+to run the same suite, but also publish your application.
+
+All of this is defined in the `.gitlab-ci.yml` file.
+
+To create a `.gitlab-ci.yml` file:
+
+1. Go to **Project overview > Details**.
+1. Above the file list, select the branch you want to commit to,
+ click the plus icon, then select **New file**:
+
+ ![New file](img/new_file_v13_6.png)
+
+1. For the **Filename**, type `.gitlab-ci.yml` and in the larger window,
+ paste this sample code:
+
+ ```yaml
+ build-job:
+ stage: build
+ script:
+ - echo "Hello, $GITLAB_USER_LOGIN!"
+
+ test-job1:
+ stage: test
+ script:
+ - echo "This job tests something"
+
+ test-job2:
+ stage: test
+ script:
+ - echo "This job tests something, but takes more time than test-job1."
+ - echo "After the echo commands complete, it runs the sleep command for 20 seconds"
+ - echo "which simulates a test that runs 20 seconds longer than test-job1"
+ - sleep 20
+
+ deploy-prod:
+ stage: deploy
+ script:
+ - echo "This job deploys something from the $CI_COMMIT_BRANCH branch."
+ ```
+
+ `$GITLAB_USER_LOGIN` and `$CI_COMMIT_BRANCH` are
+ [predefined variables](../variables/predefined_variables.md)
+ that populate when the job runs.
+
+1. Click **Commit changes**.
+
+The pipeline starts when the commit is committed.
+
+#### `.gitlab-ci.yml` tips
+
+- If you want the runner to use a Docker image to run the jobs, edit the `.gitlab-ci.yml` file
+ to include your image name:
+
+ ```yaml
+ default:
+ image: ruby:2.7.2
+ ```
+
+ This command tells the runner to use a Ruby image from Docker Hub.
+
+- To validate your `.gitlab-ci.yml` file, use the
+ [CI Lint tool](../lint.md), which is available in every project.
+- You can also use [CI/CD configuration visualization](../pipeline_editor/index.md#visualize-ci-configuration) to
+ view a graphical representation of your `.gitlab-ci.yml` file.
+- For the complete `.gitlab-ci.yml` syntax, see
+ [the `.gitlab-ci.yml` reference topic](../yaml/README.md).
+
+### View the status of your pipeline and jobs
+
+When you committed your changes, a pipeline started.
+
+To view your pipeline:
+
+- Go **CI/CD > Pipelines**.
+
+ A pipeline with three stages should be displayed:
+
+ ![Three stages](img/three_stages_v13_6.png)
+
+- To view a visual representation of your pipeline, click the pipeline ID.
+
+ ![Pipeline graph](img/pipeline_graph_v13_6.png)
+
+- To view details of a job, click the job name, for example, `deploy-prod`.
+
+ ![Job details](img/job_details_v13_6.png)
+
+If the job status is `stuck`, check to ensure a runner is probably configured for the project.
diff --git a/doc/ci/services/README.md b/doc/ci/services/README.md
index 71c2be70de3..c94d6e3ea80 100644
--- a/doc/ci/services/README.md
+++ b/doc/ci/services/README.md
@@ -1,21 +1,8 @@
---
-stage: Verify
-group: Runner
-info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
-comments: false
-type: index
+redirect_to: 'index.md'
---
-# GitLab CI services examples
+This document was moved to [another location](index.md).
-The [`services`](../docker/using_docker_images.md#what-is-a-service)
-keyword defines a Docker image that runs during a `job` linked to the
-Docker image that the image keyword defines. This allows you to access
-the service image during build time.
-
-The service image can run any application, but the most common use
-case is to run a database container, for example:
-
-- [Using MySQL](mysql.md)
-- [Using PostgreSQL](postgres.md)
-- [Using Redis](redis.md)
+
+
diff --git a/doc/ci/services/index.md b/doc/ci/services/index.md
new file mode 100644
index 00000000000..71c2be70de3
--- /dev/null
+++ b/doc/ci/services/index.md
@@ -0,0 +1,21 @@
+---
+stage: Verify
+group: Runner
+info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
+comments: false
+type: index
+---
+
+# GitLab CI services examples
+
+The [`services`](../docker/using_docker_images.md#what-is-a-service)
+keyword defines a Docker image that runs during a `job` linked to the
+Docker image that the image keyword defines. This allows you to access
+the service image during build time.
+
+The service image can run any application, but the most common use
+case is to run a database container, for example:
+
+- [Using MySQL](mysql.md)
+- [Using PostgreSQL](postgres.md)
+- [Using Redis](redis.md)
diff --git a/doc/ci/ssh_keys/README.md b/doc/ci/ssh_keys/README.md
index a5410d53a95..c94d6e3ea80 100644
--- a/doc/ci/ssh_keys/README.md
+++ b/doc/ci/ssh_keys/README.md
@@ -1,212 +1,8 @@
---
-stage: Verify
-group: Continuous Integration
-info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
-type: tutorial
+redirect_to: 'index.md'
---
-# Using SSH keys with GitLab CI/CD
+This document was moved to [another location](index.md).
-GitLab currently doesn't have built-in support for managing SSH keys in a build
-environment (where the GitLab Runner runs).
-
-The SSH keys can be useful when:
-
-1. You want to checkout internal submodules
-1. You want to download private packages using your package manager (e.g., Bundler)
-1. You want to deploy your application to your own server, or, for example, Heroku
-1. You want to execute SSH commands from the build environment to a remote server
-1. You want to rsync files from the build environment to a remote server
-
-If anything of the above rings a bell, then you most likely need an SSH key.
-
-The most widely supported method is to inject an SSH key into your build
-environment by extending your `.gitlab-ci.yml`, and it's a solution which works
-with any type of [executor](https://docs.gitlab.com/runner/executors/)
-(Docker, shell, etc.).
-
-## How it works
-
-1. Create a new SSH key pair locally with [`ssh-keygen`](https://linux.die.net/man/1/ssh-keygen)
-1. Add the private key as a [variable](../variables/README.md) to
- your project
-1. Run the [`ssh-agent`](https://linux.die.net/man/1/ssh-agent) during job to load
- the private key.
-1. Copy the public key to the servers you want to have access to (usually in
- `~/.ssh/authorized_keys`) or add it as a [deploy key](../../ssh/README.md#deploy-keys)
- if you are accessing a private GitLab repository.
-
-The private key is displayed in the job log, unless you enable
-[debug logging](../variables/README.md#debug-logging). You might also want to
-check the [visibility of your pipelines](../pipelines/settings.md#visibility-of-pipelines).
-
-## SSH keys when using the Docker executor
-
-When your CI/CD jobs run inside Docker containers (meaning the environment is
-contained) and you want to deploy your code in a private server, you need a way
-to access it. This is where an SSH key pair comes in handy.
-
-1. You first need to create an SSH key pair. For more information, follow
- the instructions to [generate an SSH key](../../ssh/README.md#generating-a-new-ssh-key-pair).
- **Do not** add a passphrase to the SSH key, or the `before_script` will
- prompt for it.
-
-1. Create a new [variable](../variables/README.md#gitlab-cicd-environment-variables).
- As **Key** enter the name `SSH_PRIVATE_KEY` and in the **Value** field paste
- the content of your _private_ key that you created earlier.
-
-1. Modify your `.gitlab-ci.yml` with a `before_script` action. In the following
- example, a Debian based image is assumed. Edit to your needs:
-
- ```yaml
- before_script:
- ##
- ## Install ssh-agent if not already installed, it is required by Docker.
- ## (change apt-get to yum if you use an RPM-based image)
- ##
- - 'command -v ssh-agent >/dev/null || ( apt-get update -y && apt-get install openssh-client -y )'
-
- ##
- ## Run ssh-agent (inside the build environment)
- ##
- - eval $(ssh-agent -s)
-
- ##
- ## Add the SSH key stored in SSH_PRIVATE_KEY variable to the agent store
- ## We're using tr to fix line endings which makes ed25519 keys work
- ## without extra base64 encoding.
- ## https://gitlab.com/gitlab-examples/ssh-private-key/issues/1#note_48526556
- ##
- - echo "$SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add -
-
- ##
- ## Create the SSH directory and give it the right permissions
- ##
- - mkdir -p ~/.ssh
- - chmod 700 ~/.ssh
-
- ##
- ## Optionally, if you will be using any Git commands, set the user name and
- ## and email.
- ##
- # - git config --global user.email "user@example.com"
- # - git config --global user.name "User name"
- ```
-
- The [`before_script`](../yaml/README.md#before_script) can be set globally
- or per-job.
-
-1. Make sure the private server's [SSH host keys are verified](#verifying-the-ssh-host-keys).
-
-1. As a final step, add the _public_ key from the one you created in the first
- step to the services that you want to have an access to from within the build
- environment. If you are accessing a private GitLab repository you need to add
- it as a [deploy key](../../ssh/README.md#deploy-keys).
-
-That's it! You can now have access to private servers or repositories in your
-build environment.
-
-## SSH keys when using the Shell executor
-
-If you are using the Shell executor and not Docker, it is easier to set up an
-SSH key.
-
-You can generate the SSH key from the machine that GitLab Runner is installed
-on, and use that key for all projects that are run on this machine.
-
-1. First, log in to the server that runs your jobs.
-
-1. Then, from the terminal, log in as the `gitlab-runner` user:
-
- ```shell
- sudo su - gitlab-runner
- ```
-
-1. Generate the SSH key pair as described in the instructions to
- [generate an SSH key](../../ssh/README.md#generating-a-new-ssh-key-pair).
- **Do not** add a passphrase to the SSH key, or the `before_script` will
- prompt for it.
-
-1. As a final step, add the _public_ key from the one you created earlier to the
- services that you want to have an access to from within the build environment.
- If you are accessing a private GitLab repository you need to add it as a
- [deploy key](../../ssh/README.md#deploy-keys).
-
-After generating the key, try to sign in to the remote server to accept the
-fingerprint:
-
-```shell
-ssh example.com
-```
-
-For accessing repositories on GitLab.com, you would use `git@gitlab.com`.
-
-## Verifying the SSH host keys
-
-It is a good practice to check the private server's own public key to make sure
-you are not being targeted by a man-in-the-middle attack. If anything
-suspicious happens, you notice it because the job fails (the SSH
-connection fails when the public keys don't match).
-
-To find out the host keys of your server, run the `ssh-keyscan` command from a
-trusted network (ideally, from the private server itself):
-
-```shell
-## Use the domain name
-ssh-keyscan example.com
-
-## Or use an IP
-ssh-keyscan 1.2.3.4
-```
-
-Create a new [variable](../variables/README.md#gitlab-cicd-environment-variables) with
-`SSH_KNOWN_HOSTS` as "Key", and as a "Value" add the output of `ssh-keyscan`.
-
-If you need to connect to multiple servers, all the server host keys
-need to be collected in the **Value** of the variable, one key per line.
-
-NOTE:
-By using a variable instead of `ssh-keyscan` directly inside
-`.gitlab-ci.yml`, it has the benefit that you don't have to change `.gitlab-ci.yml`
-if the host domain name changes for some reason. Also, the values are predefined
-by you, meaning that if the host keys suddenly change, the CI/CD job doesn't fail,
-so there's something wrong with the server or the network.
-
-Now that the `SSH_KNOWN_HOSTS` variable is created, in addition to the
-[content of `.gitlab-ci.yml`](#ssh-keys-when-using-the-docker-executor)
-above, here's what more you need to add:
-
-```yaml
-before_script:
- ##
- ## Assuming you created the SSH_KNOWN_HOSTS variable, uncomment the
- ## following two lines.
- ##
- - echo "$SSH_KNOWN_HOSTS" >> ~/.ssh/known_hosts
- - chmod 644 ~/.ssh/known_hosts
-
- ##
- ## Alternatively, use ssh-keyscan to scan the keys of your private server.
- ## Replace example.com with your private server's domain name. Repeat that
- ## command if you have more than one server to connect to.
- ##
- # - ssh-keyscan example.com >> ~/.ssh/known_hosts
- # - chmod 644 ~/.ssh/known_hosts
-
- ##
- ## You can optionally disable host key checking. Be aware that by adding that
- ## you are susceptible to man-in-the-middle attacks.
- ## WARNING: Use this only with the Docker executor, if you use it with shell
- ## you will overwrite your user's SSH config.
- ##
- # - '[[ -f /.dockerenv ]] && echo -e "Host *\n\tStrictHostKeyChecking no\n\n" >> ~/.ssh/config'
-```
-
-## Example project
-
-We have set up an [Example SSH Project](https://gitlab.com/gitlab-examples/ssh-private-key/) 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
-moments the changes is picked by a public runner and the job starts.
+
+
diff --git a/doc/ci/ssh_keys/index.md b/doc/ci/ssh_keys/index.md
new file mode 100644
index 00000000000..40b19c7e68b
--- /dev/null
+++ b/doc/ci/ssh_keys/index.md
@@ -0,0 +1,212 @@
+---
+stage: Verify
+group: Continuous Integration
+info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
+type: tutorial
+---
+
+# Using SSH keys with GitLab CI/CD
+
+GitLab currently doesn't have built-in support for managing SSH keys in a build
+environment (where the GitLab Runner runs).
+
+The SSH keys can be useful when:
+
+1. You want to checkout internal submodules
+1. You want to download private packages using your package manager (e.g., Bundler)
+1. You want to deploy your application to your own server, or, for example, Heroku
+1. You want to execute SSH commands from the build environment to a remote server
+1. You want to rsync files from the build environment to a remote server
+
+If anything of the above rings a bell, then you most likely need an SSH key.
+
+The most widely supported method is to inject an SSH key into your build
+environment by extending your `.gitlab-ci.yml`, and it's a solution which works
+with any type of [executor](https://docs.gitlab.com/runner/executors/)
+(Docker, shell, etc.).
+
+## How it works
+
+1. Create a new SSH key pair locally with [`ssh-keygen`](https://linux.die.net/man/1/ssh-keygen)
+1. Add the private key as a [variable](../variables/README.md) to
+ your project
+1. Run the [`ssh-agent`](https://linux.die.net/man/1/ssh-agent) during job to load
+ the private key.
+1. Copy the public key to the servers you want to have access to (usually in
+ `~/.ssh/authorized_keys`) or add it as a [deploy key](../../ssh/README.md#deploy-keys)
+ if you are accessing a private GitLab repository.
+
+The private key is displayed in the job log, unless you enable
+[debug logging](../variables/README.md#debug-logging). You might also want to
+check the [visibility of your pipelines](../pipelines/settings.md#visibility-of-pipelines).
+
+## SSH keys when using the Docker executor
+
+When your CI/CD jobs run inside Docker containers (meaning the environment is
+contained) and you want to deploy your code in a private server, you need a way
+to access it. This is where an SSH key pair comes in handy.
+
+1. You first need to create an SSH key pair. For more information, follow
+ the instructions to [generate an SSH key](../../ssh/README.md#generate-an-ssh-key-pair).
+ **Do not** add a passphrase to the SSH key, or the `before_script` will
+ prompt for it.
+
+1. Create a new [variable](../variables/README.md#gitlab-cicd-environment-variables).
+ As **Key** enter the name `SSH_PRIVATE_KEY` and in the **Value** field paste
+ the content of your _private_ key that you created earlier.
+
+1. Modify your `.gitlab-ci.yml` with a `before_script` action. In the following
+ example, a Debian based image is assumed. Edit to your needs:
+
+ ```yaml
+ before_script:
+ ##
+ ## Install ssh-agent if not already installed, it is required by Docker.
+ ## (change apt-get to yum if you use an RPM-based image)
+ ##
+ - 'command -v ssh-agent >/dev/null || ( apt-get update -y && apt-get install openssh-client -y )'
+
+ ##
+ ## Run ssh-agent (inside the build environment)
+ ##
+ - eval $(ssh-agent -s)
+
+ ##
+ ## Add the SSH key stored in SSH_PRIVATE_KEY variable to the agent store
+ ## We're using tr to fix line endings which makes ed25519 keys work
+ ## without extra base64 encoding.
+ ## https://gitlab.com/gitlab-examples/ssh-private-key/issues/1#note_48526556
+ ##
+ - echo "$SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add -
+
+ ##
+ ## Create the SSH directory and give it the right permissions
+ ##
+ - mkdir -p ~/.ssh
+ - chmod 700 ~/.ssh
+
+ ##
+ ## Optionally, if you will be using any Git commands, set the user name and
+ ## and email.
+ ##
+ # - git config --global user.email "user@example.com"
+ # - git config --global user.name "User name"
+ ```
+
+ The [`before_script`](../yaml/README.md#before_script) can be set globally
+ or per-job.
+
+1. Make sure the private server's [SSH host keys are verified](#verifying-the-ssh-host-keys).
+
+1. As a final step, add the _public_ key from the one you created in the first
+ step to the services that you want to have an access to from within the build
+ environment. If you are accessing a private GitLab repository you need to add
+ it as a [deploy key](../../ssh/README.md#deploy-keys).
+
+That's it! You can now have access to private servers or repositories in your
+build environment.
+
+## SSH keys when using the Shell executor
+
+If you are using the Shell executor and not Docker, it is easier to set up an
+SSH key.
+
+You can generate the SSH key from the machine that GitLab Runner is installed
+on, and use that key for all projects that are run on this machine.
+
+1. First, log in to the server that runs your jobs.
+
+1. Then, from the terminal, log in as the `gitlab-runner` user:
+
+ ```shell
+ sudo su - gitlab-runner
+ ```
+
+1. Generate the SSH key pair as described in the instructions to
+ [generate an SSH key](../../ssh/README.md#generate-an-ssh-key-pair).
+ **Do not** add a passphrase to the SSH key, or the `before_script` will
+ prompt for it.
+
+1. As a final step, add the _public_ key from the one you created earlier to the
+ services that you want to have an access to from within the build environment.
+ If you are accessing a private GitLab repository you need to add it as a
+ [deploy key](../../ssh/README.md#deploy-keys).
+
+After generating the key, try to sign in to the remote server to accept the
+fingerprint:
+
+```shell
+ssh example.com
+```
+
+For accessing repositories on GitLab.com, you would use `git@gitlab.com`.
+
+## Verifying the SSH host keys
+
+It is a good practice to check the private server's own public key to make sure
+you are not being targeted by a man-in-the-middle attack. If anything
+suspicious happens, you notice it because the job fails (the SSH
+connection fails when the public keys don't match).
+
+To find out the host keys of your server, run the `ssh-keyscan` command from a
+trusted network (ideally, from the private server itself):
+
+```shell
+## Use the domain name
+ssh-keyscan example.com
+
+## Or use an IP
+ssh-keyscan 1.2.3.4
+```
+
+Create a new [variable](../variables/README.md#gitlab-cicd-environment-variables) with
+`SSH_KNOWN_HOSTS` as "Key", and as a "Value" add the output of `ssh-keyscan`.
+
+If you need to connect to multiple servers, all the server host keys
+need to be collected in the **Value** of the variable, one key per line.
+
+NOTE:
+By using a variable instead of `ssh-keyscan` directly inside
+`.gitlab-ci.yml`, it has the benefit that you don't have to change `.gitlab-ci.yml`
+if the host domain name changes for some reason. Also, the values are predefined
+by you, meaning that if the host keys suddenly change, the CI/CD job doesn't fail,
+so there's something wrong with the server or the network.
+
+Now that the `SSH_KNOWN_HOSTS` variable is created, in addition to the
+[content of `.gitlab-ci.yml`](#ssh-keys-when-using-the-docker-executor)
+above, here's what more you need to add:
+
+```yaml
+before_script:
+ ##
+ ## Assuming you created the SSH_KNOWN_HOSTS variable, uncomment the
+ ## following two lines.
+ ##
+ - echo "$SSH_KNOWN_HOSTS" >> ~/.ssh/known_hosts
+ - chmod 644 ~/.ssh/known_hosts
+
+ ##
+ ## Alternatively, use ssh-keyscan to scan the keys of your private server.
+ ## Replace example.com with your private server's domain name. Repeat that
+ ## command if you have more than one server to connect to.
+ ##
+ # - ssh-keyscan example.com >> ~/.ssh/known_hosts
+ # - chmod 644 ~/.ssh/known_hosts
+
+ ##
+ ## You can optionally disable host key checking. Be aware that by adding that
+ ## you are susceptible to man-in-the-middle attacks.
+ ## WARNING: Use this only with the Docker executor, if you use it with shell
+ ## you will overwrite your user's SSH config.
+ ##
+ # - '[[ -f /.dockerenv ]] && echo -e "Host *\n\tStrictHostKeyChecking no\n\n" >> ~/.ssh/config'
+```
+
+## Example project
+
+We have set up an [Example SSH Project](https://gitlab.com/gitlab-examples/ssh-private-key/) 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
+moments the changes is picked by a public runner and the job starts.
diff --git a/doc/ci/variables/predefined_variables.md b/doc/ci/variables/predefined_variables.md
index 701fe33b53f..48cfa6dbc6f 100644
--- a/doc/ci/variables/predefined_variables.md
+++ b/doc/ci/variables/predefined_variables.md
@@ -22,8 +22,8 @@ Kubernetes-specific environment variables are detailed in the
| Variable | GitLab | Runner | Description |
|-----------------------------------------------|--------|--------|-------------|
-| `CHAT_CHANNEL` | 10.6 | all | Source chat channel which triggered the [ChatOps](../chatops/README.md) command. |
-| `CHAT_INPUT` | 10.6 | all | Additional arguments passed in the [ChatOps](../chatops/README.md) command. |
+| `CHAT_CHANNEL` | 10.6 | all | Source chat channel which triggered the [ChatOps](../chatops/index.md) command. |
+| `CHAT_INPUT` | 10.6 | all | Additional arguments passed in the [ChatOps](../chatops/index.md) command. |
| `CI` | all | 0.4 | Mark that job is executed in CI environment. |
| `CI_API_V4_URL` | 11.7 | all | The GitLab API v4 root URL. |
| `CI_BUILDS_DIR` | all | 11.10 | Top-level directory where builds are executed. |
diff --git a/doc/ci/yaml/README.md b/doc/ci/yaml/README.md
index f3ad2932e9a..7bd691aabba 100644
--- a/doc/ci/yaml/README.md
+++ b/doc/ci/yaml/README.md
@@ -13,7 +13,7 @@ type: reference
This document lists the configuration options for your GitLab `.gitlab-ci.yml` file.
-- For a quick introduction to GitLab CI/CD, follow the [quick start guide](../quick_start/README.md).
+- For a quick introduction to GitLab CI/CD, follow the [quick start guide](../quick_start/index.md).
- For a collection of examples, see [GitLab CI/CD Examples](../examples/README.md).
- To view a large `.gitlab-ci.yml` file used in an enterprise, see the [`.gitlab-ci.yml` file for `gitlab`](https://gitlab.com/gitlab-org/gitlab/blob/master/.gitlab-ci.yml).
@@ -543,7 +543,7 @@ Used to specify [a Docker image](../docker/using_docker_images.md#what-is-an-ima
For:
- Usage examples, see [Define `image` and `services` from `.gitlab-ci.yml`](../docker/using_docker_images.md#define-image-and-services-from-gitlab-ciyml).
-- Detailed usage information, refer to [Docker integration](../docker/README.md) documentation.
+- Detailed usage information, refer to [Docker integration](../docker/index.md) documentation.
#### `image:name`
@@ -564,8 +564,8 @@ Used to specify a [service Docker image](../docker/using_docker_images.md#what-i
For:
- Usage examples, see [Define `image` and `services` from `.gitlab-ci.yml`](../docker/using_docker_images.md#define-image-and-services-from-gitlab-ciyml).
-- Detailed usage information, refer to [Docker integration](../docker/README.md) documentation.
-- For example services, see [GitLab CI/CD Services](../services/README.md).
+- Detailed usage information, refer to [Docker integration](../docker/index.md) documentation.
+- For example services, see [GitLab CI/CD Services](../services/index.md).
##### `services:name`
@@ -1253,7 +1253,7 @@ check the value of the `$CI_PIPELINE_SOURCE` variable:
| Value | Description |
|-------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `api` | For pipelines triggered by the [pipelines API](../../api/pipelines.md#create-a-new-pipeline). |
-| `chat` | For pipelines created by using a [GitLab ChatOps](../chatops/README.md) command. |
+| `chat` | For pipelines created by using a [GitLab ChatOps](../chatops/index.md) command. |
| `external` | When you use CI services other than GitLab. |
| `external_pull_request_event` | When an external pull request on GitHub is created or updated. See [Pipelines for external pull requests](../ci_cd_for_external_repos/index.md#pipelines-for-external-pull-requests). |
| `merge_request_event` | For pipelines created when a merge request is created or updated. Required to enable [merge request pipelines](../merge_request_pipelines/index.md), [merged results pipelines](../merge_request_pipelines/pipelines_for_merged_results/index.md), and [merge trains](../merge_request_pipelines/pipelines_for_merged_results/merge_trains/index.md). |
@@ -1553,7 +1553,7 @@ In addition, `only` and `except` can use special keywords:
|--------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `api` | For pipelines triggered by the [pipelines API](../../api/pipelines.md#create-a-new-pipeline). |
| `branches` | When the Git reference for a pipeline is a branch. |
-| `chat` | For pipelines created by using a [GitLab ChatOps](../chatops/README.md) command. |
+| `chat` | For pipelines created by using a [GitLab ChatOps](../chatops/index.md) command. |
| `external` | When you use CI services other than GitLab. |
| `external_pull_requests` | When an external pull request on GitHub is created or updated (See [Pipelines for external pull requests](../ci_cd_for_external_repos/index.md#pipelines-for-external-pull-requests)). |
| `merge_requests` | For pipelines created when a merge request is created or updated. Enables [merge request pipelines](../merge_request_pipelines/index.md), [merged results pipelines](../merge_request_pipelines/pipelines_for_merged_results/index.md), and [merge trains](../merge_request_pipelines/pipelines_for_merged_results/merge_trains/index.md). |
diff --git a/doc/development/chatops_on_gitlabcom.md b/doc/development/chatops_on_gitlabcom.md
index a2a0005f7cb..6cb2c7cc2dc 100644
--- a/doc/development/chatops_on_gitlabcom.md
+++ b/doc/development/chatops_on_gitlabcom.md
@@ -61,6 +61,6 @@ To request access to ChatOps on GitLab.com:
## See also
-- [ChatOps Usage](../ci/chatops/README.md)
+- [ChatOps Usage](../ci/chatops/index.md)
- [Understanding EXPLAIN plans](understanding_explain_plans.md)
- [Feature Groups](feature_flags/development.md#feature-groups)
diff --git a/doc/development/contributing/index.md b/doc/development/contributing/index.md
index 329303558b0..7a1c189e087 100644
--- a/doc/development/contributing/index.md
+++ b/doc/development/contributing/index.md
@@ -181,11 +181,21 @@ reasons for including it.
`@mention` a maintainer in merge requests that contain:
- More than 500 changes.
-- Any major breaking changes.
+- Any major [breaking changes](#breaking-changes).
- External libraries.
If you are not sure who to mention, the reviewer will do this for you early in the merge request process.
+#### Breaking changes
+
+A "breaking change" is any change that requires users to make a corresponding change to their code, settings, or workflow. "Users" might be humans, API clients, or even code classes that "use" another class. Examples of breaking changes include:
+
+- Removing a user-facing feature without a replacement/workaround.
+- Changing the definition of an existing API (by re-naming query parameters, changing routes, etc.).
+- Removing a public method from a code class.
+
+A breaking change can be considered "major" if it affects many users, or represents a significant change in behavior.
+
#### Issues workflow
This [documentation](issue_workflow.md) outlines the current issue workflow:
diff --git a/doc/development/contributing/merge_request_workflow.md b/doc/development/contributing/merge_request_workflow.md
index 5c8068fdee7..81de680710b 100644
--- a/doc/development/contributing/merge_request_workflow.md
+++ b/doc/development/contributing/merge_request_workflow.md
@@ -150,7 +150,7 @@ Commit messages should follow the guidelines below, for reasons explained by Chr
#### Why these standards matter
1. Consistent commit messages that follow these guidelines make the history more readable.
-1. Concise standard commit messages helps to identify breaking changes for a deployment or ~"master:broken" quicker when
+1. Concise standard commit messages helps to identify [breaking changes](index.md#breaking-changes) for a deployment or ~"master:broken" quicker when
reviewing commits between two points in time.
#### Commit message template
diff --git a/doc/development/experiment_guide/index.md b/doc/development/experiment_guide/index.md
index 5d77c0ca0e9..21c61324dc1 100644
--- a/doc/development/experiment_guide/index.md
+++ b/doc/development/experiment_guide/index.md
@@ -325,7 +325,7 @@ Note that the use of this method requires that we have first [recorded the user
### Enable the experiment
-After all merge requests have been merged, use [`chatops`](../../ci/chatops/README.md) in the
+After all merge requests have been merged, use [`chatops`](../../ci/chatops/index.md) in the
[appropriate channel](../feature_flags/controls.md#communicate-the-change) to start the experiment for 10% of the users.
The feature flag should have the name of the experiment with the `_experiment_percentage` suffix appended.
For visibility, please also share any commands run against production in the `#s_growth` channel:
diff --git a/doc/development/feature_flags/controls.md b/doc/development/feature_flags/controls.md
index cda4f4c905c..21ac152c469 100644
--- a/doc/development/feature_flags/controls.md
+++ b/doc/development/feature_flags/controls.md
@@ -37,7 +37,7 @@ easier to measure the impact of both separately.
The GitLab feature library (using
[Flipper](https://github.com/jnunemaker/flipper), and covered in the [Feature
Flags process](process.md) guide) supports rolling out changes to a percentage of
-time to users. This in turn can be controlled using [GitLab ChatOps](../../ci/chatops/README.md).
+time to users. This in turn can be controlled using [GitLab ChatOps](../../ci/chatops/index.md).
For an up to date list of feature flag commands please see [the source
code](https://gitlab.com/gitlab-com/chatops/blob/master/lib/chatops/commands/feature.rb).
diff --git a/doc/development/prometheus_metrics.md b/doc/development/prometheus_metrics.md
index 7296ea726ca..05a623448bf 100644
--- a/doc/development/prometheus_metrics.md
+++ b/doc/development/prometheus_metrics.md
@@ -75,5 +75,10 @@ This section describes how to add new metrics for self-monitoring
1. Select the appropriate name for your metric. Refer to the guidelines
for [Prometheus metric names](https://prometheus.io/docs/practices/naming/#metric-names).
1. Update the list of [GitLab Prometheus metrics](../administration/monitoring/prometheus/gitlab_metrics.md).
+1. Carefully choose what labels you want to add to your metric. Values with high cardinality,
+like `project_path`, or `project_id` are strongly discouraged because they can affect our services
+availability due to the fact that each set of labels is exposed as a new entry in the `/metrics` endpoint.
+For example, a histogram with 10 buckets and a label with 100 values would generate 1000
+entries in the export endpoint.
1. Trigger the relevant page or code that records the new metric.
1. Check that the new metric appears at `/-/metrics`.
diff --git a/doc/integration/slash_commands.md b/doc/integration/slash_commands.md
index 80be6daa3a8..0dcf86cc46d 100644
--- a/doc/integration/slash_commands.md
+++ b/doc/integration/slash_commands.md
@@ -26,7 +26,7 @@ Taking the trigger term as `project-name`, the commands are:
| `/project-name issue move to ` | Moves issue ID `` to `` |
| `/project-name issue comment ` | Adds a new comment to an issue with ID `` and comment body `` |
| `/project-name deploy to ` | Deploy from the `` environment to the `` environment |
-| `/project-name run ` | Execute [ChatOps](../ci/chatops/README.md) job `` on `master` |
+| `/project-name run ` | Execute [ChatOps](../ci/chatops/index.md) job `` on `master` |
If you are using the [GitLab Slack application](../user/project/integrations/gitlab_slack_application.md) for
your GitLab.com projects, [add the `gitlab` keyword at the beginning of the command](../user/project/integrations/gitlab_slack_application.md#usage).
diff --git a/doc/intro/README.md b/doc/intro/README.md
index 5df4efe5307..96d7806aa66 100644
--- a/doc/intro/README.md
+++ b/doc/intro/README.md
@@ -38,7 +38,7 @@ Create merge requests and review code.
Use the built-in continuous integration in GitLab.
-- [Get started with GitLab CI/CD](../ci/quick_start/README.md)
+- [Get started with GitLab CI/CD](../ci/quick_start/index.md)
## Install and Update
diff --git a/doc/ssh/README.md b/doc/ssh/README.md
index 42ba355422c..8d8fc683158 100644
--- a/doc/ssh/README.md
+++ b/doc/ssh/README.md
@@ -17,179 +17,145 @@ GitLab remote server without supplying your username or password each time.
This page can help you configure secure SSH keys which you can use to help secure
connections to GitLab repositories.
-- If you need information on creating SSH keys, start with our [options for SSH keys](#options-for-ssh-keys).
+- If you need information on creating SSH keys, start with our [options for SSH keys](#supported-ssh-key-types).
- If you have SSH keys dedicated for your GitLab account, you may be interested in [Working with non-default SSH key pair paths](#working-with-non-default-ssh-key-pair-paths).
-- If you already have an SSH key pair, you can go to how you can [add an SSH key to your GitLab account](#adding-an-ssh-key-to-your-gitlab-account).
+- If you already have an SSH key pair, you can go to how you can [add an SSH key to your GitLab account](#add-an-ssh-key-to-your-gitlab-account).
-## Requirements
+## Prerequisites
-To support SSH, GitLab requires the installation of the OpenSSH client, which
-comes pre-installed on GNU/Linux and macOS, as well as on Windows 10.
+To use SSH to communicate with GitLab, you need:
-Make sure that your system includes SSH version 6.5 or newer, as that excludes
-the now insecure MD5 signature scheme. The following command returns the version of
-SSH installed on your system:
+- The OpenSSH client, which comes pre-installed on GNU/Linux, macOS, and Windows 10.
+- SSH version 6.5 or later. Earlier versions used an MD5 signature, which is not secure.
-```shell
-ssh -V
-```
+To view the version of SSH installed on your system, run `ssh -V`.
-While GitLab does [not support installation on Microsoft Windows](../install/requirements.md#microsoft-windows),
-you can set up SSH keys to set up Windows [as a client](#options-for-microsoft-windows).
+GitLab does [not support installation on Microsoft Windows](../install/requirements.md#microsoft-windows),
+but you can set up SSH keys on the Windows [client](#options-for-microsoft-windows).
-## Options for SSH keys
+## Supported SSH key types
-GitLab supports the use of RSA, DSA, ECDSA, and ED25519 keys.
+To communicate with GitLab, you can use the following SSH key types:
-- GitLab has [deprecated](https://about.gitlab.com/releases/2018/06/22/gitlab-11-0-released/#support-for-dsa-ssh-keys) DSA keys in GitLab 11.0.
-- As noted in [Practical Cryptography With Go](https://leanpub.com/gocrypto/read#leanpub-auto-ecdsa), the security issues related to DSA also apply to ECDSA.
+- [ED25519](#ed25519-ssh-keys)
+- [RSA](#rsa-ssh-keys)
+- DSA ([Deprecated](https://about.gitlab.com/releases/2018/06/22/gitlab-11-0-released/#support-for-dsa-ssh-keys) in GitLab 11.0.)
+- ECDSA (As noted in [Practical Cryptography With Go](https://leanpub.com/gocrypto/read#leanpub-auto-ecdsa), the security issues related to DSA also apply to ECDSA.)
-NOTE:
-Available documentation suggests that ED25519 is more secure. If you use an RSA key, the US National Institute of Science and Technology in [Publication 800-57 Part 3 (PDF)](https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-57Pt3r1.pdf) recommends a key size of at least 2048 bits.
-
-Therefore, our documentation focuses on the use of ED25519 and RSA keys.
-
-Administrators can [restrict which keys should be permitted and their minimum lengths](../security/ssh_keys_restrictions.md).
-
-## Review existing SSH keys
-
-If you have existing SSH keys, you may be able to use them to help secure connections with GitLab
-repositories. By default, SSH keys on Linux and macOS systems are stored in the user's home directory,
-in the `.ssh/` subdirectory. The following table includes default filenames for each SSH key algorithm:
-
-| Algorithm | Public key | Private key |
-| --------- | ---------- | ----------- |
-| ED25519 (preferred) | `id_ed25519.pub` | `id_ed25519` |
-| RSA (at least 2048-bit key size) | `id_rsa.pub` | `id_rsa` |
-| DSA (deprecated) | `id_dsa.pub` | `id_dsa` |
-| ECDSA | `id_ecdsa.pub` | `id_ecdsa` |
-
-For recommendations, see [options for SSH keys](#options-for-ssh-keys).
-
-## Generating a new SSH key pair
-
-If you want to create:
-
-- An ED25519 key, read [ED25519 SSH keys](#ed25519-ssh-keys).
-- An RSA key, read [RSA SSH keys](#rsa-ssh-keys).
+Administrators can [restrict which keys are permitted and their minimum lengths](../security/ssh_keys_restrictions.md).
### ED25519 SSH keys
The book [Practical Cryptography With Go](https://leanpub.com/gocrypto/read#leanpub-auto-chapter-5-digital-signatures)
suggests that [ED25519](https://ed25519.cr.yp.to/) keys are more secure and performant than RSA keys.
-As OpenSSH 6.5 introduced ED25519 SSH keys in 2014, they should be available on any current
-operating system.
-
-You can create and configure an ED25519 key with the following command:
-
-```shell
-ssh-keygen -t ed25519 -C ""
-```
-
-The `-C` flag, with a quoted comment such as an email address, is an optional way to label your SSH keys.
-
-You'll see a response similar to:
-
-```plaintext
-Generating public/private ed25519 key pair.
-Enter file in which to save the key (/home/user/.ssh/id_ed25519):
-```
-
-For guidance, proceed to the [common steps](#common-steps-for-generating-an-ssh-key-pair).
+OpenSSH 6.5 introduced ED25519 SSH keys in 2014 and they should be available on most
+operating systems.
### RSA SSH keys
-If you use RSA keys for SSH, the US National Institute of Standards and Technology recommends
-that you use a key size of [at least 2048 bits](https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-57Pt3r1.pdf).
-By default, the `ssh-keygen` command creates an 1024-bit RSA key.
+Available documentation suggests that ED25519 is more secure than RSA.
-You can create and configure an RSA key with the following command, substituting if desired for the minimum recommended key size of `2048`:
+If you use an RSA key, the US National Institute of Science and Technology in
+[Publication 800-57 Part 3 (PDF)](https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-57Pt3r1.pdf)
+recommends a key size of at least 2048 bits. The default key size depends on your version of `ssh-keygen`.
+Review the `man` page for your installed `ssh-keygen` command for details.
-```shell
-ssh-keygen -t rsa -b 2048 -C "email@example.com"
-```
+## See if you have an existing SSH key pair
-The `-C` flag, with a quoted comment such as an email address, is an optional way to label your SSH keys.
+Before you create a key pair, see if a key pair already exists.
-You'll see a response similar to:
+1. On Linux or macOS, go to your home directory.
+1. Go to the `.ssh/` subdirectory.
+1. See if a file with one of the following formats exists:
-```plaintext
-Generating public/private rsa key pair.
-Enter file in which to save the key (/home/user/.ssh/id_rsa):
-```
+ | Algorithm | Public key | Private key |
+ | --------- | ---------- | ----------- |
+ | ED25519 (preferred) | `id_ed25519.pub` | `id_ed25519` |
+ | RSA (at least 2048-bit key size) | `id_rsa.pub` | `id_rsa` |
+ | DSA (deprecated) | `id_dsa.pub` | `id_dsa` |
+ | ECDSA | `id_ecdsa.pub` | `id_ecdsa` |
-For guidance, proceed to the [common steps](#common-steps-for-generating-an-ssh-key-pair).
+## Generate an SSH key pair
-NOTE:
-If you have OpenSSH version 7.8 or below, consider the problems associated
-with [encoding](#rsa-keys-and-openssh-from-versions-65-to-78).
+If you do not have an existing SSH key pair, generate a new one.
-### Common steps for generating an SSH key pair
+1. Open a terminal.
+1. Type `ssh-keygen -t` followed by the key type and an optional comment.
+ This comment is included in the `.pub` file that's created.
+ You may want to use an email address for the comment.
+
+ For example, for ED25519:
-Whether you're creating a [ED25519](#ed25519-ssh-keys) or an [RSA](#rsa-ssh-keys) key, you've started with the `ssh-keygen` command.
-At this point, you'll see the following message in the command line (for ED25519 keys):
+ ```shell
+ ssh-keygen -t ed25519 -C ""
+ ```
-```plaintext
-Generating public/private ed25519 key pair.
-Enter file in which to save the key (/home/user/.ssh/id_ed25519):
-```
+ For 2048-bit RSA:
-If you don't already have an SSH key pair and are not generating a [deploy key](#deploy-keys),
-accept the suggested file and directory. Your SSH client uses
-the resulting SSH key pair with no additional configuration.
+ ```shell
+ ssh-keygen -t rsa -b 2048 -C ""
+ ```
-Alternatively, you can save the new SSH key pair in a different location.
-You can assign the directory and filename of your choice.
-You can also dedicate that SSH key pair to a [specific host](#working-with-non-default-ssh-key-pair-paths).
+1. Press Enter. Output similar to the following is displayed:
-After assigning a file to save your SSH key, you can set up
-a [passphrase](https://www.ssh.com/ssh/passphrase/) for your SSH key:
+ ```plaintext
+ Generating public/private ed25519 key pair.
+ Enter file in which to save the key (/home/user/.ssh/id_ed25519):
+ ```
-```plaintext
-Enter passphrase (empty for no passphrase):
-Enter same passphrase again:
-```
+1. Accept the suggested filename and directory, unless you are generating a [deploy key](#deploy-keys)
+ or want to save in a specific directory where you store other keys.
-If successful, you'll see confirmation of where the `ssh-keygen` command
-saved your identification and private key.
+ You can also dedicate the SSH key pair to a [specific host](#working-with-non-default-ssh-key-pair-paths).
-When needed, you can update the passphrase with the following command:
+1. Specify a [passphrase](https://www.ssh.com/ssh/passphrase/):
-```shell
-ssh-keygen -p -f /path/to/ssh_key
-```
+ ```plaintext
+ Enter passphrase (empty for no passphrase):
+ Enter same passphrase again:
+ ```
-### RSA keys and OpenSSH from versions 6.5 to 7.8
+1. A confirmation is displayed, including information about where your files are stored.
-Before OpenSSH 7.8, the default public key fingerprint for RSA keys was based on MD5,
-and is therefore insecure.
+A public and private key are generated.
+[Add the public SSH key to your GitLab account](#add-an-ssh-key-to-your-gitlab-account) and keep
+the private key secure.
-If your version of OpenSSH lies between version 6.5 to version 7.8 (inclusive),
-run `ssh-keygen` with the `-o` option to save your private SSH keys in the more secure
+### Update your SSH key passphrase
+
+You can update the passphrase for your SSH key.
+
+1. Open a terminal and type this command:
+
+ ```shell
+ ssh-keygen -p -f /path/to/ssh_key
+ ```
+
+1. At the prompts, type the passphrase and press Enter.
+
+### Upgrade your RSA key pair to a more secure format
+
+If your version of OpenSSH is between 6.5 and 7.8,
+you can save your private RSA SSH keys in a more secure
OpenSSH format.
-If you already have an RSA SSH key pair to use with GitLab, consider upgrading it
-to use the more secure password encryption format. You can do so with the following command:
+1. Open a terminal and type this command:
-```shell
-ssh-keygen -o -f ~/.ssh/id_rsa
-```
+ ```shell
+ ssh-keygen -o -f ~/.ssh/id_rsa
+ ```
-Alternatively, you can generate a new RSA key with the more secure encryption format with
-the following command:
+ Alternatively, you can generate a new RSA key with the more secure encryption format with
+ the following command:
-```shell
-ssh-keygen -o -t rsa -b 4096 -C "email@example.com"
-```
+ ```shell
+ ssh-keygen -o -t rsa -b 4096 -C ""
+ ```
-NOTE:
-As noted in the `ssh-keygen` man page, ED25519 already encrypts keys to the more secure
-OpenSSH format.
+## Add an SSH key to your GitLab account
-## Adding an SSH key to your GitLab account
-
-Now you can copy the SSH key you created to your GitLab account. To do so, follow these steps:
+Now you can copy the SSH key you created to your GitLab account.
1. Copy your **public** SSH key to a location that saves information in text format.
The following options saves information for ED25519 keys to the clipboard
diff --git a/doc/user/application_security/dast/index.md b/doc/user/application_security/dast/index.md
index 3ce60aa31e8..4a7fbec43e8 100644
--- a/doc/user/application_security/dast/index.md
+++ b/doc/user/application_security/dast/index.md
@@ -842,6 +842,17 @@ The site is validated and an active scan can run against it.
If a validated site profile's target URL is edited, the site is no longer validated.
+### Revoke a site validation
+
+To revoke validation from a site profile:
+
+1. From your project's home page, go to **Security & Compliance > Configuration**.
+1. Select **Manage** in the **DAST Profiles** row.
+1. Select **Revoke validation** beside the validated profile.
+1. Select **Revoke validation**.
+
+The site profile's validation is revoked. An active scan cannot be run against it or any other profile with the same URL.
+
#### Validated site profile headers
The following are code samples of how you could provide the required site profile header in your
diff --git a/doc/user/project/repository/index.md b/doc/user/project/repository/index.md
index c4f5d330f63..42fa5895a60 100644
--- a/doc/user/project/repository/index.md
+++ b/doc/user/project/repository/index.md
@@ -43,7 +43,7 @@ You can either use the user interface (UI), or connect your local computer
with GitLab [through the command line](../../../gitlab-basics/command-line-commands.md#start-working-on-your-project).
To configure [GitLab CI/CD](../../../ci/README.md) to build, test, and deploy
-your code, add a file called [`.gitlab-ci.yml`](../../../ci/quick_start/README.md)
+your code, add a file called [`.gitlab-ci.yml`](../../../ci/quick_start/index.md)
to your repository's root.
**From the user interface:**
diff --git a/lib/api/deployments.rb b/lib/api/deployments.rb
index 5346fcf03c9..d0c842bb19d 100644
--- a/lib/api/deployments.rb
+++ b/lib/api/deployments.rb
@@ -36,7 +36,7 @@ module API
get ':id/deployments' do
authorize! :read_deployment, user_project
- deployments = DeploymentsFinder.new(user_project, params).execute
+ deployments = DeploymentsFinder.new(params.merge(project: user_project)).execute
present paginate(deployments), with: Entities::Deployment
end
diff --git a/lib/api/entities/ci/job.rb b/lib/api/entities/ci/job.rb
index 7fe1a802e24..76487ed01dc 100644
--- a/lib/api/entities/ci/job.rb
+++ b/lib/api/entities/ci/job.rb
@@ -9,6 +9,9 @@ module API
expose :job_artifacts, as: :artifacts, using: ::API::Entities::Ci::JobArtifact
expose :runner, with: ::API::Entities::Runner
expose :artifacts_expire_at
+ expose :tag_list do |job|
+ job.tags.map(&:name).sort
+ end
end
end
end
diff --git a/lib/api/jobs.rb b/lib/api/jobs.rb
index c09b01f5b4e..390dbc892e2 100644
--- a/lib/api/jobs.rb
+++ b/lib/api/jobs.rb
@@ -45,7 +45,7 @@ module API
builds = user_project.builds.order('id DESC')
builds = filter_builds(builds, params[:scope])
- builds = builds.preload(:user, :job_artifacts_archive, :job_artifacts, :runner, pipeline: :project)
+ builds = builds.preload(:user, :job_artifacts_archive, :job_artifacts, :runner, :tags, pipeline: :project)
present paginate(builds), with: Entities::Ci::Job
end
# rubocop: enable CodeReuse/ActiveRecord
diff --git a/lib/gitlab/cycle_analytics/summary/deploy.rb b/lib/gitlab/cycle_analytics/summary/deploy.rb
index 5125c8e64ee..3cba8eba111 100644
--- a/lib/gitlab/cycle_analytics/summary/deploy.rb
+++ b/lib/gitlab/cycle_analytics/summary/deploy.rb
@@ -15,9 +15,16 @@ module Gitlab
private
def deployments_count
- query = @project.deployments.success.where("created_at >= ?", @from)
- query = query.where("created_at <= ?", @to) if @to
- query.count
+ if Feature.enabled?(:query_deploymenys_via_finished_at_in_vsa)
+ DeploymentsFinder
+ .new(project: @project, finished_after: @from, finished_before: @to, status: :success)
+ .execute
+ .count
+ else
+ query = @project.deployments.success.where("created_at >= ?", @from)
+ query = query.where("created_at <= ?", @to) if @to
+ query.count
+ end
end
end
end
diff --git a/lib/tasks/gitlab/graphql.rake b/lib/tasks/gitlab/graphql.rake
index b108c3411e9..e4eb4604138 100644
--- a/lib/tasks/gitlab/graphql.rake
+++ b/lib/tasks/gitlab/graphql.rake
@@ -48,9 +48,21 @@ namespace :gitlab do
if summary == :client_query
$stdout.puts " - client query"
elsif errs.present?
- $stdout.puts " - invalid query"
+ $stdout.puts " - invalid query".color(:red)
else
- $stdout.puts " - complexity: #{defn.complexity(GitlabSchema)}"
+ complexity = defn.complexity(GitlabSchema)
+ color = case complexity
+ when 0..GitlabSchema::DEFAULT_MAX_COMPLEXITY
+ :green
+ when GitlabSchema::DEFAULT_MAX_COMPLEXITY..GitlabSchema::AUTHENTICATED_COMPLEXITY
+ :yellow
+ when GitlabSchema::AUTHENTICATED_COMPLEXITY..GitlabSchema::ADMIN_COMPLEXITY
+ :orange
+ else
+ :red
+ end
+
+ $stdout.puts " - complexity: #{complexity}".color(color)
end
$stdout.puts ""
@@ -72,10 +84,10 @@ namespace :gitlab do
when :client_query
warn("SKIP #{defn.file}: client query")
else
- warn("OK #{defn.file}") if errs.empty?
+ warn("#{'OK'.color(:green)} #{defn.file}") if errs.empty?
errs.each do |err|
warn(<<~MSG)
- ERROR #{defn.file}: #{err.message} (at #{err.path.join('.')})
+ #{'ERROR'.color(:red)} #{defn.file}: #{err.message} (at #{err.path.join('.')})
MSG
end
end
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index 2ac62c8f808..a6662403fc7 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -9194,6 +9194,9 @@ msgstr ""
msgid "DastSiteValidation|Could not create validation token. Please try again."
msgstr ""
+msgid "DastSiteValidation|Could not revoke validation. Please try again."
+msgstr ""
+
msgid "DastSiteValidation|Download validation text file"
msgstr ""
@@ -9203,6 +9206,9 @@ msgstr ""
msgid "DastSiteValidation|Retry validation"
msgstr ""
+msgid "DastSiteValidation|Revoke validation"
+msgstr ""
+
msgid "DastSiteValidation|Step 1 - Choose site validation method"
msgstr ""
@@ -9227,6 +9233,11 @@ msgstr ""
msgid "DastSiteValidation|The validation is in progress. Please wait..."
msgstr ""
+msgid "DastSiteValidation|This will affect %d other profile targeting the same URL."
+msgid_plural "DastSiteValidation|This will affect %d other profiles targeting the same URL."
+msgstr[0] ""
+msgstr[1] ""
+
msgid "DastSiteValidation|Validate"
msgstr ""
@@ -9245,6 +9256,9 @@ msgstr ""
msgid "DastSiteValidation|Validation succeeded. Both active and passive scans can be run against the target site."
msgstr ""
+msgid "DastSiteValidation|You will not be able to run active scans against %{url}."
+msgstr ""
+
msgid "Data is still calculating..."
msgstr ""
@@ -23047,6 +23061,9 @@ msgstr ""
msgid "ProjectSettings|Require"
msgstr ""
+msgid "ProjectSettings|Require an associated issue from Jira"
+msgstr ""
+
msgid "ProjectSettings|Requirements"
msgstr ""
diff --git a/package.json b/package.json
index d74bd8eb30a..0501336d72c 100644
--- a/package.json
+++ b/package.json
@@ -177,9 +177,9 @@
"docdash": "^1.0.2",
"eslint": "7.19.0",
"eslint-import-resolver-jest": "3.0.0",
- "eslint-import-resolver-webpack": "^0.12.1",
- "eslint-plugin-jasmine": "^4.1.0",
- "eslint-plugin-no-jquery": "^2.3.0",
+ "eslint-import-resolver-webpack": "0.12.1",
+ "eslint-plugin-jasmine": "4.1.0",
+ "eslint-plugin-no-jquery": "2.3.1",
"gettext-extractor": "^3.4.3",
"gettext-extractor-vue": "^4.0.2",
"istanbul-lib-coverage": "^3.0.0",
diff --git a/spec/finders/deployments_finder_spec.rb b/spec/finders/deployments_finder_spec.rb
index e4e0f366eeb..82868daec98 100644
--- a/spec/finders/deployments_finder_spec.rb
+++ b/spec/finders/deployments_finder_spec.rb
@@ -3,10 +3,10 @@
require 'spec_helper'
RSpec.describe DeploymentsFinder do
- subject { described_class.new(project, params).execute }
+ subject { described_class.new(params).execute }
- let(:project) { create(:project, :public, :test_repo) }
- let(:params) { {} }
+ let_it_be(:project) { create(:project, :public, :test_repo) }
+ let(:params) { { project: project } }
describe "#execute" do
it 'returns all deployments by default' do
@@ -14,9 +14,17 @@ RSpec.describe DeploymentsFinder do
is_expected.to match_array(deployments)
end
+ context 'when project is missing' do
+ let(:params) { {} }
+
+ it 'returns nothing' do
+ is_expected.to eq([])
+ end
+ end
+
describe 'filtering' do
context 'when updated_at filters are specified' do
- let(:params) { { updated_before: 1.day.ago, updated_after: 3.days.ago } }
+ let(:params) { { project: project, updated_before: 1.day.ago, updated_after: 3.days.ago } }
let!(:deployment_1) { create(:deployment, :success, project: project, updated_at: 2.days.ago) }
let!(:deployment_2) { create(:deployment, :success, project: project, updated_at: 4.days.ago) }
let!(:deployment_3) { create(:deployment, :success, project: project, updated_at: 1.hour.ago) }
@@ -37,7 +45,7 @@ RSpec.describe DeploymentsFinder do
create(:deployment, project: project, environment: environment2)
end
- let(:params) { { environment: environment1.name } }
+ let(:params) { { project: project, environment: environment1.name } }
it 'returns deployments for the given environment' do
is_expected.to match_array([deployment1])
@@ -47,7 +55,7 @@ RSpec.describe DeploymentsFinder do
context 'when the deployment status is specified' do
let!(:deployment1) { create(:deployment, :success, project: project) }
let!(:deployment2) { create(:deployment, :failed, project: project) }
- let(:params) { { status: 'success' } }
+ let(:params) { { project: project, status: 'success' } }
it 'returns deployments for the given environment' do
is_expected.to match_array([deployment1])
@@ -55,36 +63,64 @@ RSpec.describe DeploymentsFinder do
end
context 'when using an invalid deployment status' do
- let(:params) { { status: 'kittens' } }
+ let(:params) { { project: project, status: 'kittens' } }
it 'raises ArgumentError' do
expect { subject }.to raise_error(ArgumentError)
end
end
+
+ context 'when filtering by finished time' do
+ let!(:deployment_1) { create(:deployment, :success, project: project, finished_at: 2.days.ago) }
+ let!(:deployment_2) { create(:deployment, :success, project: project, finished_at: 4.days.ago) }
+ let!(:deployment_3) { create(:deployment, :success, project: project, finished_at: 5.hours.ago) }
+
+ context 'when filtering by finished_after and finished_before' do
+ let(:params) { { project: project, finished_after: 3.days.ago, finished_before: 1.day.ago } }
+
+ it { is_expected.to match_array([deployment_1]) }
+ end
+
+ context 'when the finished_before parameter is missing' do
+ let(:params) { { project: project, finished_after: 3.days.ago } }
+
+ it { is_expected.to match_array([deployment_1, deployment_3]) }
+ end
+
+ context 'when finished_after is missing' do
+ let(:params) { { project: project, finished_before: 1.day.ago } }
+
+ it 'does not apply any filters on finished time' do
+ is_expected.to match_array([deployment_1, deployment_2, deployment_3])
+ end
+ end
+ end
end
describe 'ordering' do
using RSpec::Parameterized::TableSyntax
- let(:params) { { order_by: order_by, sort: sort } }
+ let(:params) { { project: project, order_by: order_by, sort: sort } }
- let!(:deployment_1) { create(:deployment, :success, project: project, iid: 11, ref: 'master', created_at: 2.days.ago, updated_at: Time.now) }
- let!(:deployment_2) { create(:deployment, :success, project: project, iid: 12, ref: 'feature', created_at: 1.day.ago, updated_at: 2.hours.ago) }
- let!(:deployment_3) { create(:deployment, :success, project: project, iid: 8, ref: 'video', created_at: Time.now, updated_at: 1.hour.ago) }
+ let!(:deployment_1) { create(:deployment, :success, project: project, iid: 11, ref: 'master', created_at: 2.days.ago, updated_at: Time.now, finished_at: 3.hours.ago) }
+ let!(:deployment_2) { create(:deployment, :success, project: project, iid: 12, ref: 'feature', created_at: 1.day.ago, updated_at: 2.hours.ago, finished_at: 1.hour.ago) }
+ let!(:deployment_3) { create(:deployment, :success, project: project, iid: 8, ref: 'video', created_at: Time.now, updated_at: 1.hour.ago, finished_at: 2.hours.ago) }
where(:order_by, :sort, :ordered_deployments) do
- 'created_at' | 'asc' | [:deployment_1, :deployment_2, :deployment_3]
- 'created_at' | 'desc' | [:deployment_3, :deployment_2, :deployment_1]
- 'id' | 'asc' | [:deployment_1, :deployment_2, :deployment_3]
- 'id' | 'desc' | [:deployment_3, :deployment_2, :deployment_1]
- 'iid' | 'asc' | [:deployment_3, :deployment_1, :deployment_2]
- 'iid' | 'desc' | [:deployment_2, :deployment_1, :deployment_3]
- 'ref' | 'asc' | [:deployment_2, :deployment_1, :deployment_3]
- 'ref' | 'desc' | [:deployment_3, :deployment_1, :deployment_2]
- 'updated_at' | 'asc' | [:deployment_2, :deployment_3, :deployment_1]
- 'updated_at' | 'desc' | [:deployment_1, :deployment_3, :deployment_2]
- 'invalid' | 'asc' | [:deployment_1, :deployment_2, :deployment_3]
- 'iid' | 'err' | [:deployment_3, :deployment_1, :deployment_2]
+ 'created_at' | 'asc' | [:deployment_1, :deployment_2, :deployment_3]
+ 'created_at' | 'desc' | [:deployment_3, :deployment_2, :deployment_1]
+ 'id' | 'asc' | [:deployment_1, :deployment_2, :deployment_3]
+ 'id' | 'desc' | [:deployment_3, :deployment_2, :deployment_1]
+ 'iid' | 'asc' | [:deployment_3, :deployment_1, :deployment_2]
+ 'iid' | 'desc' | [:deployment_2, :deployment_1, :deployment_3]
+ 'ref' | 'asc' | [:deployment_2, :deployment_1, :deployment_3]
+ 'ref' | 'desc' | [:deployment_3, :deployment_1, :deployment_2]
+ 'updated_at' | 'asc' | [:deployment_2, :deployment_3, :deployment_1]
+ 'updated_at' | 'desc' | [:deployment_1, :deployment_3, :deployment_2]
+ 'finished_at' | 'asc' | [:deployment_1, :deployment_3, :deployment_2]
+ 'finished_at' | 'desc' | [:deployment_2, :deployment_3, :deployment_1]
+ 'invalid' | 'asc' | [:deployment_1, :deployment_2, :deployment_3]
+ 'iid' | 'err' | [:deployment_3, :deployment_1, :deployment_2]
end
with_them do
@@ -95,7 +131,7 @@ RSpec.describe DeploymentsFinder do
end
describe 'transform `created_at` sorting to `id` sorting' do
- let(:params) { { order_by: 'created_at', sort: 'asc' } }
+ let(:params) { { project: project, order_by: 'created_at', sort: 'asc' } }
it 'sorts by only one column' do
expect(subject.order_values.size).to eq(1)
@@ -107,7 +143,7 @@ RSpec.describe DeploymentsFinder do
end
describe 'tie-breaker for `updated_at` sorting' do
- let(:params) { { order_by: 'updated_at', sort: 'asc' } }
+ let(:params) { { project: project, order_by: 'updated_at', sort: 'asc' } }
it 'sorts by two columns' do
expect(subject.order_values.size).to eq(2)
diff --git a/spec/fixtures/api/schemas/public_api/v4/job.json b/spec/fixtures/api/schemas/public_api/v4/job.json
index c038ae0a664..b50479841a9 100644
--- a/spec/fixtures/api/schemas/public_api/v4/job.json
+++ b/spec/fixtures/api/schemas/public_api/v4/job.json
@@ -18,6 +18,7 @@
"web_url",
"artifacts",
"artifacts_expire_at",
+ "tag_list",
"runner"
],
"properties": {
@@ -53,6 +54,9 @@
]
},
"artifacts_expire_at": { "type": ["null", "string"] },
+ "tag_list": {
+ "type": "array"
+ },
"runner": {
"oneOf": [
{ "type": "null" },
diff --git a/spec/frontend/packages/list/components/packages_list_app_spec.js b/spec/frontend/packages/list/components/packages_list_app_spec.js
index 36dd73666ea..b3094b81c85 100644
--- a/spec/frontend/packages/list/components/packages_list_app_spec.js
+++ b/spec/frontend/packages/list/components/packages_list_app_spec.js
@@ -93,6 +93,7 @@ describe('packages_list_app', () => {
it('call requestPackagesList on page:changed', () => {
mountComponent();
+ store.dispatch.mockClear();
const list = findListComponent();
list.vm.$emit('page:changed', 1);
@@ -107,14 +108,6 @@ describe('packages_list_app', () => {
expect(store.dispatch).toHaveBeenCalledWith('requestDeletePackage', 'foo');
});
- it('calls requestPackagesList on sort:changed', () => {
- mountComponent();
-
- const list = findListComponent();
- list.vm.$emit('sort:changed');
- expect(store.dispatch).toHaveBeenCalledWith('requestPackagesList');
- });
-
it('does not call requestPackagesList two times on render', () => {
mountComponent();
@@ -142,10 +135,11 @@ describe('packages_list_app', () => {
expect(findPackageSearch().exists()).toBe(true);
});
- it.each(['sort:changed', 'filter:changed'])('on %p fetches data from the store', (event) => {
+ it('on update fetches data from the store', () => {
mountComponent();
+ store.dispatch.mockClear();
- findPackageSearch().vm.$emit(event);
+ findPackageSearch().vm.$emit('update');
expect(store.dispatch).toHaveBeenCalledWith('requestPackagesList');
});
diff --git a/spec/frontend/packages/list/components/packages_search_spec.js b/spec/frontend/packages/list/components/packages_search_spec.js
index 23a8d3fb871..5a1b0ce2c80 100644
--- a/spec/frontend/packages/list/components/packages_search_spec.js
+++ b/spec/frontend/packages/list/components/packages_search_spec.js
@@ -1,8 +1,9 @@
import Vuex from 'vuex';
-import { GlSorting, GlSortingItem, GlFilteredSearch } from '@gitlab/ui';
import { shallowMount, createLocalVue } from '@vue/test-utils';
import component from '~/packages/list/components/package_search.vue';
+import RegistrySearch from '~/vue_shared/components/registry/registry_search.vue';
import PackageTypeToken from '~/packages/list/components/tokens/package_type_token.vue';
+import getTableHeaders from '~/packages/list/utils';
const localVue = createLocalVue();
localVue.use(Vuex);
@@ -10,12 +11,8 @@ localVue.use(Vuex);
describe('Package Search', () => {
let wrapper;
let store;
- let sorting;
- let sortingItems;
- const findPackageListSorting = () => wrapper.find(GlSorting);
- const findSortingItems = () => wrapper.findAll(GlSortingItem);
- const findFilteredSearch = () => wrapper.find(GlFilteredSearch);
+ const findRegistrySearch = () => wrapper.find(RegistrySearch);
const createStore = (isGroupPage) => {
const state = {
@@ -40,9 +37,6 @@ describe('Package Search', () => {
wrapper = shallowMount(component, {
localVue,
store,
- stubs: {
- GlSortingItem,
- },
});
};
@@ -51,95 +45,63 @@ describe('Package Search', () => {
wrapper = null;
});
- describe('searching', () => {
- it('has a filtered-search component', () => {
- mountComponent();
+ it('has a registry search component', () => {
+ mountComponent();
- expect(findFilteredSearch().exists()).toBe(true);
- });
-
- it('binds the correct props to filtered-search', () => {
- mountComponent();
-
- expect(findFilteredSearch().props()).toMatchObject({
- value: [],
- placeholder: 'Filter results',
- availableTokens: wrapper.vm.tokens,
- });
- });
-
- it('updates vuex when value changes', () => {
- mountComponent();
-
- findFilteredSearch().vm.$emit('input', ['foo']);
-
- expect(store.dispatch).toHaveBeenCalledWith('setFilter', ['foo']);
- });
-
- it('emits filter:changed on submit event', () => {
- mountComponent();
-
- findFilteredSearch().vm.$emit('submit');
- expect(wrapper.emitted('filter:changed')).toEqual([[]]);
- });
-
- it('emits filter:changed on clear event and reset vuex', () => {
- mountComponent();
-
- findFilteredSearch().vm.$emit('clear');
-
- expect(store.dispatch).toHaveBeenCalledWith('setFilter', []);
- expect(wrapper.emitted('filter:changed')).toEqual([[]]);
- });
-
- it('has a PackageTypeToken token', () => {
- mountComponent();
-
- expect(findFilteredSearch().props('availableTokens')).toEqual(
- expect.arrayContaining([
- expect.objectContaining({ token: PackageTypeToken, type: 'type', icon: 'package' }),
- ]),
- );
+ expect(findRegistrySearch().exists()).toBe(true);
+ expect(findRegistrySearch().props()).toMatchObject({
+ filter: store.state.filter,
+ sorting: store.state.sorting,
+ tokens: expect.arrayContaining([
+ expect.objectContaining({ token: PackageTypeToken, type: 'type', icon: 'package' }),
+ ]),
+ sortableFields: getTableHeaders(),
});
});
- describe('sorting', () => {
- describe('when is in projects', () => {
- beforeEach(() => {
- mountComponent();
- sorting = findPackageListSorting();
- sortingItems = findSortingItems();
- });
+ it.each`
+ isGroupPage | page
+ ${false} | ${'project'}
+ ${true} | ${'group'}
+ `('in a $page page binds the right props', ({ isGroupPage }) => {
+ mountComponent(isGroupPage);
- it('has all the sortable items', () => {
- expect(sortingItems).toHaveLength(wrapper.vm.sortableFields.length);
- });
-
- it('on sort change set sorting in vuex and emit event', () => {
- sorting.vm.$emit('sortDirectionChange');
- expect(store.dispatch).toHaveBeenCalledWith('setSorting', { sort: 'asc' });
- expect(wrapper.emitted('sort:changed')).toBeTruthy();
- });
-
- it('on sort item click set sorting and emit event', () => {
- const item = sortingItems.at(0);
- const { orderBy } = wrapper.vm.sortableFields[0];
- item.vm.$emit('click');
- expect(store.dispatch).toHaveBeenCalledWith('setSorting', { orderBy });
- expect(wrapper.emitted('sort:changed')).toBeTruthy();
- });
+ expect(findRegistrySearch().props()).toMatchObject({
+ filter: store.state.filter,
+ sorting: store.state.sorting,
+ tokens: expect.arrayContaining([
+ expect.objectContaining({ token: PackageTypeToken, type: 'type', icon: 'package' }),
+ ]),
+ sortableFields: getTableHeaders(isGroupPage),
});
+ });
- describe('when is in group', () => {
- beforeEach(() => {
- mountComponent(true);
- sorting = findPackageListSorting();
- sortingItems = findSortingItems();
- });
+ it('on sorting:changed emits update event and calls vuex setSorting', () => {
+ const payload = { sort: 'foo' };
- it('has all the sortable items', () => {
- expect(sortingItems).toHaveLength(wrapper.vm.sortableFields.length);
- });
- });
+ mountComponent();
+
+ findRegistrySearch().vm.$emit('sorting:changed', payload);
+
+ expect(store.dispatch).toHaveBeenCalledWith('setSorting', payload);
+ expect(wrapper.emitted('update')).toEqual([[]]);
+ });
+
+ it('on filter:changed calls vuex setFilter', () => {
+ const payload = ['foo'];
+
+ mountComponent();
+
+ findRegistrySearch().vm.$emit('filter:changed', payload);
+
+ expect(store.dispatch).toHaveBeenCalledWith('setFilter', payload);
+ });
+
+ it('on filter:submit emits update event', () => {
+ mountComponent();
+
+ findRegistrySearch().vm.$emit('filter:submit');
+
+ expect(wrapper.emitted('update')).toEqual([[]]);
});
});
diff --git a/spec/frontend/vue_shared/components/registry/registry_search_spec.js b/spec/frontend/vue_shared/components/registry/registry_search_spec.js
new file mode 100644
index 00000000000..28bdb275756
--- /dev/null
+++ b/spec/frontend/vue_shared/components/registry/registry_search_spec.js
@@ -0,0 +1,105 @@
+import { GlSorting, GlSortingItem, GlFilteredSearch } from '@gitlab/ui';
+import { shallowMount } from '@vue/test-utils';
+import component from '~/vue_shared/components/registry/registry_search.vue';
+
+describe('Registry Search', () => {
+ let wrapper;
+
+ const findPackageListSorting = () => wrapper.find(GlSorting);
+ const findSortingItems = () => wrapper.findAll(GlSortingItem);
+ const findFilteredSearch = () => wrapper.find(GlFilteredSearch);
+
+ const defaultProps = {
+ filter: [],
+ sorting: { sort: 'asc', orderBy: 'name' },
+ tokens: ['foo'],
+ sortableFields: [{ label: 'name', orderBy: 'name' }, { label: 'baz' }],
+ };
+
+ const mountComponent = (propsData = defaultProps) => {
+ wrapper = shallowMount(component, {
+ propsData,
+ stubs: {
+ GlSortingItem,
+ },
+ });
+ };
+
+ afterEach(() => {
+ wrapper.destroy();
+ wrapper = null;
+ });
+
+ describe('searching', () => {
+ it('has a filtered-search component', () => {
+ mountComponent();
+
+ expect(findFilteredSearch().exists()).toBe(true);
+ });
+
+ it('binds the correct props to filtered-search', () => {
+ mountComponent();
+
+ expect(findFilteredSearch().props()).toMatchObject({
+ value: [],
+ placeholder: 'Filter results',
+ availableTokens: wrapper.vm.tokens,
+ });
+ });
+
+ it('emits filter:changed when value changes', () => {
+ mountComponent();
+
+ findFilteredSearch().vm.$emit('input', 'foo');
+
+ expect(wrapper.emitted('filter:changed')).toEqual([['foo']]);
+ });
+
+ it('emits filter:submit on submit event', () => {
+ mountComponent();
+
+ findFilteredSearch().vm.$emit('submit');
+ expect(wrapper.emitted('filter:submit')).toEqual([[]]);
+ });
+
+ it('emits filter:changed and filter:submit on clear event', () => {
+ mountComponent();
+
+ findFilteredSearch().vm.$emit('clear');
+
+ expect(wrapper.emitted('filter:changed')).toEqual([[[]]]);
+ expect(wrapper.emitted('filter:submit')).toEqual([[]]);
+ });
+
+ it('binds tokens prop', () => {
+ mountComponent();
+
+ expect(findFilteredSearch().props('availableTokens')).toEqual(defaultProps.tokens);
+ });
+ });
+
+ describe('sorting', () => {
+ it('has all the sortable items', () => {
+ mountComponent();
+
+ expect(findSortingItems()).toHaveLength(defaultProps.sortableFields.length);
+ });
+
+ it('on sort change emits sorting:changed event', () => {
+ mountComponent();
+
+ findPackageListSorting().vm.$emit('sortDirectionChange');
+ expect(wrapper.emitted('sorting:changed')).toEqual([[{ sort: 'desc' }]]);
+ });
+
+ it('on sort item click emits sorting:changed event ', () => {
+ mountComponent();
+
+ findSortingItems().at(0).vm.$emit('click');
+
+ expect(wrapper.emitted('sorting:changed')).toEqual([
+ [{ orderBy: defaultProps.sortableFields[0].orderBy }],
+ ]);
+ });
+ });
+});
diff --git a/spec/lib/gitlab/cycle_analytics/stage_summary_spec.rb b/spec/lib/gitlab/cycle_analytics/stage_summary_spec.rb
index 21503dc1501..76578340f7b 100644
--- a/spec/lib/gitlab/cycle_analytics/stage_summary_spec.rb
+++ b/spec/lib/gitlab/cycle_analytics/stage_summary_spec.rb
@@ -218,7 +218,7 @@ RSpec.describe Gitlab::CycleAnalytics::StageSummary do
context 'when `to` is given' do
before do
- Timecop.freeze(5.days.from_now) { create(:deployment, :success, project: project) }
+ Timecop.freeze(5.days.from_now) { create(:deployment, :success, project: project, finished_at: Time.zone.now) }
end
it 'finds records created between `from` and `to` range' do
@@ -230,12 +230,34 @@ RSpec.describe Gitlab::CycleAnalytics::StageSummary do
end
context 'when `from` and `to` are within a day' do
- it 'returns the number of deployments made on that day' do
- freeze_time do
- create(:deployment, :success, project: project)
- options[:from] = options[:to] = Time.now
+ context 'when query_deploymenys_via_finished_at_in_vsa feature flag is off' do
+ before do
+ stub_feature_flags(query_deploymenys_via_finished_at_in_vsa: false)
+ end
- expect(subject).to eq('1')
+ it 'returns the number of deployments made on that day' do
+ freeze_time do
+ create(:deployment, :success, project: project)
+ options[:from] = options[:to] = Time.zone.now
+
+ expect(subject).to eq('1')
+ end
+ end
+ end
+
+ context 'when query_deploymenys_via_finished_at_in_vsa feature flag is off' do
+ before do
+ stub_feature_flags(query_deploymenys_via_finished_at_in_vsa: true)
+ end
+
+ it 'returns the number of deployments made on that day' do
+ freeze_time do
+ create(:deployment, :success, project: project, finished_at: Time.zone.now)
+ options[:from] = Time.zone.now.at_beginning_of_day
+ options[:to] = Time.zone.now.at_end_of_day
+
+ expect(subject).to eq('1')
+ end
end
end
end
diff --git a/spec/requests/api/jobs_spec.rb b/spec/requests/api/jobs_spec.rb
index 6f854a28cec..1c43ef25f14 100644
--- a/spec/requests/api/jobs_spec.rb
+++ b/spec/requests/api/jobs_spec.rb
@@ -17,7 +17,7 @@ RSpec.describe API::Jobs do
end
let!(:job) do
- create(:ci_build, :success, pipeline: pipeline,
+ create(:ci_build, :success, :tags, pipeline: pipeline,
artifacts_expire_at: 1.day.since)
end
@@ -50,6 +50,7 @@ RSpec.describe API::Jobs do
expect(json_response).not_to be_empty
expect(json_response.first['commit']['id']).to eq project.commit.id
expect(Time.parse(json_response.first['artifacts_expire_at'])).to be_like_time(job.artifacts_expire_at)
+ expect(json_response.first['tag_list'].sort).to eq job.tag_list.sort
end
context 'without artifacts and trace' do
diff --git a/spec/services/git/wiki_push_service_spec.rb b/spec/services/git/wiki_push_service_spec.rb
index 0431e06723f..df9a48d7b1c 100644
--- a/spec/services/git/wiki_push_service_spec.rb
+++ b/spec/services/git/wiki_push_service_spec.rb
@@ -288,16 +288,6 @@ RSpec.describe Git::WikiPushService, services: true do
expect { subject }.not_to raise_error
end
-
- context 'when feature flag :wiki_housekeeping is disabled' do
- it 'does not perform housekeeping' do
- stub_feature_flags(wiki_housekeeping: false)
-
- expect(housekeeping).not_to receive(:execute)
-
- subject
- end
- end
end
it 'increments the push counter' do
diff --git a/spec/support/helpers/cycle_analytics_helpers.rb b/spec/support/helpers/cycle_analytics_helpers.rb
index 6d3ac699a7c..a90cbbf3bd3 100644
--- a/spec/support/helpers/cycle_analytics_helpers.rb
+++ b/spec/support/helpers/cycle_analytics_helpers.rb
@@ -3,6 +3,32 @@
module CycleAnalyticsHelpers
include GitHelpers
+ def wait_for_stages_to_load
+ expect(page).to have_selector '.js-stage-table'
+ wait_for_requests
+ end
+
+ def select_group(target_group)
+ visit group_analytics_cycle_analytics_path(target_group)
+
+ wait_for_stages_to_load
+ end
+
+ def toggle_dropdown(field)
+ page.within("[data-testid='#{field}']") do
+ find('.dropdown-toggle').click
+
+ wait_for_requests
+
+ expect(find('.dropdown-menu')).to have_selector('.dropdown-item')
+ end
+ end
+
+ def select_dropdown_option_by_value(name, value, elem = '.dropdown-item')
+ toggle_dropdown name
+ page.find("[data-testid='#{name}'] .dropdown-menu").find("#{elem}[value='#{value}']").click
+ end
+
def create_commit_referencing_issue(issue, branch_name: generate(:branch))
project.repository.add_branch(user, branch_name, 'master')
create_commit("Commit for ##{issue.iid}", issue.project, user, branch_name)
diff --git a/yarn.lock b/yarn.lock
index 22ed696ca04..e251e5e093b 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -4604,7 +4604,7 @@ eslint-import-resolver-node@^0.3.4:
debug "^2.6.9"
resolve "^1.13.1"
-eslint-import-resolver-webpack@^0.12.1:
+eslint-import-resolver-webpack@0.12.1:
version "0.12.1"
resolved "https://registry.yarnpkg.com/eslint-import-resolver-webpack/-/eslint-import-resolver-webpack-0.12.1.tgz#771ae561e887ca4e53ee87605fbb36c5e290b0f5"
integrity sha512-O/sUAXk6GWrICiN8JUkkjdt9uZpqZHP+FVnTxtEILL6EZMaPSrnP4lGPSFwcKsv7O211maqq4Nz60+dh236hVg==
@@ -4664,7 +4664,7 @@ eslint-plugin-import@^2.22.1:
resolve "^1.17.0"
tsconfig-paths "^3.9.0"
-eslint-plugin-jasmine@^4.1.0:
+eslint-plugin-jasmine@4.1.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/eslint-plugin-jasmine/-/eslint-plugin-jasmine-4.1.0.tgz#4f6d41b1a8622348c97559cbcd29badffa74dbfa"
integrity sha512-Vfuk2Sm1ULR7MqGjVIOOEdQWyoFBfSwvwUeo9MrajVGJB3C24c9Mmj1Cgf8Qwmf3aS2bezPt1sckpKXWpd74Dw==
@@ -4676,7 +4676,7 @@ eslint-plugin-jest@^23.8.2:
dependencies:
"@typescript-eslint/experimental-utils" "^2.5.0"
-eslint-plugin-no-jquery@^2.3.0:
+eslint-plugin-no-jquery@2.3.1:
version "2.3.1"
resolved "https://registry.yarnpkg.com/eslint-plugin-no-jquery/-/eslint-plugin-no-jquery-2.3.1.tgz#1c364cb863a38cc1570c8020155b6004cca62178"
integrity sha512-/fiQUBSOMUETnfBuiK5ewvtRbek1IRTy5ov/6RZ6nlybvZ337vyGaNPWM1KgaIoIeN7dairNrPfq0h7A0tpT3A==