diff --git a/.gitlab/issue_templates/Geo Replicate a new Git repository type.md b/.gitlab/issue_templates/Geo Replicate a new Git repository type.md index 3b4e6231882..dd37cd703b1 100644 --- a/.gitlab/issue_templates/Geo Replicate a new Git repository type.md +++ b/.gitlab/issue_templates/Geo Replicate a new Git repository type.md @@ -34,6 +34,9 @@ There are three main sections below. It is a good idea to structure your merge r It is also a good idea to first open a proof-of-concept merge request. It can be helpful for working out kinks and getting initial support and feedback from the Geo team. As an example, see the [Proof of Concept to replicate Pipeline Artifacts](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/56423). +You can look into the following example for implementing replication/verification for a new Git repository type: +- [Add snippet repository verification](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/56596) + ### Modify database schemas to prepare to add Geo support for Cool Widgets You might do this section in its own merge request, but it is not required. @@ -350,6 +353,7 @@ That's all of the required database changes. module Geo class CoolWidgetReplicator < Gitlab::Geo::Replicator include ::Geo::RepositoryReplicatorStrategy + extend ::Gitlab::Utils::Override def self.model ::CoolWidget @@ -460,7 +464,7 @@ That's all of the required database changes. FactoryBot.define do factory :geo_cool_widget_registry, class: 'Geo::CoolWidgetRegistry' do - cool_widget + cool_widget # This association should have data, like a file or repository state { Geo::CoolWidgetRegistry.state_value(:pending) } trait :synced do @@ -770,6 +774,8 @@ Individual Cool Widget replication and verification data should now be available module Geo class CoolWidgetReplicator < Gitlab::Geo::Replicator ... + # REMOVE THIS LINE IF IT IS NO LONGER NEEDED + extend ::Gitlab::Utils::Override # REMOVE THIS METHOD def self.replication_enabled_by_default? diff --git a/.gitlab/issue_templates/Geo Replicate a new blob type.md b/.gitlab/issue_templates/Geo Replicate a new blob type.md index 2fc50a81056..fcb5c281fc1 100644 --- a/.gitlab/issue_templates/Geo Replicate a new blob type.md +++ b/.gitlab/issue_templates/Geo Replicate a new blob type.md @@ -34,6 +34,10 @@ There are three main sections below. It is a good idea to structure your merge r It is also a good idea to first open a proof-of-concept merge request. It can be helpful for working out kinks and getting initial support and feedback from the Geo team. As an example, see the [Proof of Concept to replicate Pipeline Artifacts](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/56423). +You can look into the following examples of MRs for implementing replication/verification for a new blob type: +- [Add db changes](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/60935) and [add verification for MR diffs using SSF](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/63309) +- [Verify Terraform state versions](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/58800) + ### Modify database schemas to prepare to add Geo support for Cool Widgets You might do this section in its own merge request, but it is not required. @@ -339,6 +343,7 @@ That's all of the required database changes. module Geo class CoolWidgetReplicator < Gitlab::Geo::Replicator include ::Geo::BlobReplicatorStrategy + extend ::Gitlab::Utils::Override def self.model ::CoolWidget @@ -426,7 +431,7 @@ That's all of the required database changes. FactoryBot.define do factory :geo_cool_widget_registry, class: 'Geo::CoolWidgetRegistry' do - cool_widget + cool_widget # This association should have data, like a file or repository state { Geo::CoolWidgetRegistry.state_value(:pending) } trait :synced do @@ -736,7 +741,10 @@ Individual Cool Widget replication and verification data should now be available module Geo class CoolWidgetReplicator < Gitlab::Geo::Replicator ... + # REMOVE THIS LINE IF IT IS NO LONGER NEEDED + extend ::Gitlab::Utils::Override + ... # REMOVE THIS METHOD def self.replication_enabled_by_default? false diff --git a/Gemfile b/Gemfile index 0a8dd0f2840..7b1396e6b53 100644 --- a/Gemfile +++ b/Gemfile @@ -496,7 +496,7 @@ gem 'flipper', '~> 0.21.0' gem 'flipper-active_record', '~> 0.21.0' gem 'flipper-active_support_cache_store', '~> 0.21.0' gem 'unleash', '~> 0.1.5' -gem 'gitlab-experiment', '~> 0.5.4' +gem 'gitlab-experiment', '~> 0.6.1' # Structured logging gem 'lograge', '~> 0.5' diff --git a/Gemfile.lock b/Gemfile.lock index d7c3651a455..7150e46caf8 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -470,7 +470,7 @@ GEM numerizer (~> 0.2) gitlab-dangerfiles (2.1.2) danger-gitlab - gitlab-experiment (0.5.4) + gitlab-experiment (0.6.1) activesupport (>= 3.0) request_store (>= 1.0) scientist (~> 1.6, >= 1.6.0) @@ -1487,7 +1487,7 @@ DEPENDENCIES github-markup (~> 1.7.0) gitlab-chronic (~> 0.10.5) gitlab-dangerfiles (~> 2.1.2) - gitlab-experiment (~> 0.5.4) + gitlab-experiment (~> 0.6.1) gitlab-fog-azure-rm (~> 1.1.1) gitlab-labkit (~> 0.18.0) gitlab-license (~> 1.5) diff --git a/app/assets/javascripts/cycle_analytics/components/formatted_stage_count.vue b/app/assets/javascripts/cycle_analytics/components/formatted_stage_count.vue new file mode 100644 index 00000000000..0fcfeb93e34 --- /dev/null +++ b/app/assets/javascripts/cycle_analytics/components/formatted_stage_count.vue @@ -0,0 +1,28 @@ + + + diff --git a/app/assets/javascripts/cycle_analytics/components/path_navigation.vue b/app/assets/javascripts/cycle_analytics/components/path_navigation.vue index c1e33f73b13..aa929e076a5 100644 --- a/app/assets/javascripts/cycle_analytics/components/path_navigation.vue +++ b/app/assets/javascripts/cycle_analytics/components/path_navigation.vue @@ -7,6 +7,7 @@ import { } from '@gitlab/ui'; import Tracking from '~/tracking'; import { OVERVIEW_STAGE_ID } from '../constants'; +import FormattedStageCount from './formatted_stage_count.vue'; export default { name: 'PathNavigation', @@ -14,6 +15,7 @@ export default { GlPath, GlSkeletonLoading, GlPopover, + FormattedStageCount, }, directives: { SafeHtml, @@ -88,10 +90,7 @@ export default { {{ s__('ValueStreamEvent|Items in stage') }}
- - +
diff --git a/app/assets/javascripts/releases/graphql/fragments/release_for_editing.fragment.graphql b/app/assets/javascripts/releases/graphql/fragments/release_for_editing.fragment.graphql index 47c5afefd78..75a73acb9ae 100644 --- a/app/assets/javascripts/releases/graphql/fragments/release_for_editing.fragment.graphql +++ b/app/assets/javascripts/releases/graphql/fragments/release_for_editing.fragment.graphql @@ -9,6 +9,7 @@ fragment ReleaseForEditing on Release { name url linkType + directAssetPath } } } diff --git a/app/assets/javascripts/releases/stores/modules/edit_new/actions.js b/app/assets/javascripts/releases/stores/modules/edit_new/actions.js index 5955ec3352e..576f099248e 100644 --- a/app/assets/javascripts/releases/stores/modules/edit_new/actions.js +++ b/app/assets/javascripts/releases/stores/modules/edit_new/actions.js @@ -165,6 +165,7 @@ const createReleaseLink = async ({ state, link }) => { name: link.name, url: link.url, linkType: link.linkType.toUpperCase(), + directAssetPath: link.directAssetPath, }, }, }); diff --git a/app/assets/javascripts/sentry/index.js b/app/assets/javascripts/sentry/index.js index a875ef84088..176745b4177 100644 --- a/app/assets/javascripts/sentry/index.js +++ b/app/assets/javascripts/sentry/index.js @@ -14,6 +14,7 @@ const index = function index() { release: gon.revision, tags: { revision: gon.revision, + feature_category: gon.feature_category, }, }); diff --git a/app/assets/javascripts/sentry/sentry_config.js b/app/assets/javascripts/sentry/sentry_config.js index bc3b2f16a6a..a3a2c794a67 100644 --- a/app/assets/javascripts/sentry/sentry_config.js +++ b/app/assets/javascripts/sentry/sentry_config.js @@ -59,16 +59,18 @@ const SentryConfig = { configure() { const { dsn, release, tags, whitelistUrls, environment } = this.options; + Sentry.init({ dsn, release, - tags, whitelistUrls, environment, ignoreErrors: this.IGNORE_ERRORS, // TODO: Remove in favor of https://gitlab.com/gitlab-org/gitlab/issues/35144 blacklistUrls: this.BLACKLIST_URLS, sampleRate: SAMPLE_RATE, }); + + Sentry.setTags(tags); }, setUser() { diff --git a/app/assets/stylesheets/page_bundles/milestone.scss b/app/assets/stylesheets/page_bundles/milestone.scss index 03dd12ec230..08d9d24d246 100644 --- a/app/assets/stylesheets/page_bundles/milestone.scss +++ b/app/assets/stylesheets/page_bundles/milestone.scss @@ -65,15 +65,32 @@ $status-box-line-height: 26px; line-height: $line-height-base; padding: 14px 16px; display: flex; + justify-content: space-between; .title { flex: 1; flex-grow: 2; } - .counter { - flex: 0; - padding-left: 16px; + .issuable-count-weight { + white-space: nowrap; + + .counter, + .weight { + color: var(--gray-500, $gray-500); + font-weight: $gl-font-weight-bold; + } + } + + &.text-white { + .issuable-count-weight svg { + fill: $white; + } + + .issuable-count-weight .counter, + .weight { + color: var(--white, $white); + } } } } diff --git a/app/experiments/application_experiment.rb b/app/experiments/application_experiment.rb index 53ea8ea2d3a..c777fdc63a1 100644 --- a/app/experiments/application_experiment.rb +++ b/app/experiments/application_experiment.rb @@ -10,22 +10,28 @@ class ApplicationExperiment < Gitlab::Experiment # rubocop:disable Gitlab/Namesp end def publish(_result = nil) - return unless should_track? # don't track events for excluded contexts + super - record_experiment if @record # record the subject in the database if the context contains a namespace, group, project, actor or user - - track(:assignment) # track that we've assigned a variant for this context - - push_to_client + publish_to_client if should_track? # publish the experiment data to the client + publish_to_database if @record # publish the experiment context to the database end - # push the experiment data to the client - def push_to_client + def publish_to_client Gon.push({ experiment: { name => signature } }, true) rescue NoMethodError # means we're not in the request cycle, and can't add to Gon. Log a warning maybe? end + def publish_to_database + # if the context contains a namespace, group, project, user, or actor + value = context.value + subject = value[:namespace] || value[:group] || value[:project] || value[:user] || value[:actor] + return unless ExperimentSubject.valid_subject?(subject) + + variant = :experimental if @variant_name != :control + Experiment.add_subject(name, variant: variant || :control, subject: subject) + end + def track(action, **event_args) return unless should_track? # don't track events for excluded contexts @@ -41,14 +47,23 @@ class ApplicationExperiment < Gitlab::Experiment # rubocop:disable Gitlab/Namesp @record = true end - def exclude! - @excluded = true - end - def control_behavior # define a default nil control behavior so we can omit it when not needed end + # TODO: remove + # This is deprecated logic as of v0.6.0 and should eventually be removed, but + # needs to stay intact for actively running experiments. The new strategy + # utilizes Digest::SHA2, a secret seed, and generates a 64-byte string. + def key_for(source, seed = name) + source = source.keys + source.values if source.is_a?(Hash) + + ingredients = Array(source).map { |v| identify(v) } + ingredients.unshift(seed) + + Digest::MD5.hexdigest(ingredients.join('|')) + end + private def feature_flag_name @@ -58,13 +73,4 @@ class ApplicationExperiment < Gitlab::Experiment # rubocop:disable Gitlab/Namesp def experiment_group? Feature.enabled?(feature_flag_name, self, type: :experiment, default_enabled: :yaml) end - - def record_experiment - subject = context.value[:namespace] || context.value[:group] || context.value[:project] || context.value[:user] || context.value[:actor] - return unless ExperimentSubject.valid_subject?(subject) - - variant = :experimental if @variant_name != :control - - Experiment.add_subject(name, variant: variant || :control, subject: subject) - end end diff --git a/app/graphql/types/release_asset_link_type.rb b/app/graphql/types/release_asset_link_type.rb index c27e1cf19b3..829e7e246db 100644 --- a/app/graphql/types/release_asset_link_type.rb +++ b/app/graphql/types/release_asset_link_type.rb @@ -20,6 +20,8 @@ module Types field :direct_asset_url, GraphQL::STRING_TYPE, null: true, description: 'Direct asset URL of the link.' + field :direct_asset_path, GraphQL::STRING_TYPE, null: true, method: :filepath, + description: 'Relative path for the direct asset link.' def direct_asset_url return object.url unless object.filepath diff --git a/app/graphql/types/snippets/blob_type.rb b/app/graphql/types/snippets/blob_type.rb index fb9ee380705..1335838935e 100644 --- a/app/graphql/types/snippets/blob_type.rb +++ b/app/graphql/types/snippets/blob_type.rb @@ -16,6 +16,10 @@ module Types description: 'Blob plain highlighted data.', null: true + field :raw_plain_data, GraphQL::STRING_TYPE, + description: 'The raw content of the blob, if the blob is text data.', + null: true + field :raw_path, GraphQL::STRING_TYPE, description: 'Blob raw content endpoint path.', null: false diff --git a/app/models/ci/application_record.rb b/app/models/ci/application_record.rb new file mode 100644 index 00000000000..f338770a938 --- /dev/null +++ b/app/models/ci/application_record.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +module Ci + # TODO: https://gitlab.com/groups/gitlab-org/-/epics/6168 + # + # Do not use this yet outside of `ci_instance_variables`. + # This class is part of a migration to move all CI classes to a new separate database. + # Initially we are only going to be moving the `Ci::InstanceVariable` model and it will be duplicated in the main and CI tables + # Do not extend this class in any other models. + class ApplicationRecord < ::ApplicationRecord + self.abstract_class = true + + if Gitlab::Database.has_config?(:ci) + connects_to database: { writing: :ci, reading: :ci } + end + end +end diff --git a/app/models/ci/instance_variable.rb b/app/models/ci/instance_variable.rb index e083caa8751..67b98a0b8b6 100644 --- a/app/models/ci/instance_variable.rb +++ b/app/models/ci/instance_variable.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true module Ci - class InstanceVariable < ApplicationRecord + class InstanceVariable < ::Ci::ApplicationRecord extend Gitlab::Ci::Model extend Gitlab::ProcessMemoryCache::Helper include Ci::NewHasVariable diff --git a/app/models/concerns/cache_markdown_field.rb b/app/models/concerns/cache_markdown_field.rb index 101bff32dfe..79b622c8dad 100644 --- a/app/models/concerns/cache_markdown_field.rb +++ b/app/models/concerns/cache_markdown_field.rb @@ -163,9 +163,9 @@ module CacheMarkdownField refs = all_references(self.author) references = {} - references[:mentioned_users_ids] = refs.mentioned_users&.pluck(:id).presence - references[:mentioned_groups_ids] = refs.mentioned_groups&.pluck(:id).presence - references[:mentioned_projects_ids] = refs.mentioned_projects&.pluck(:id).presence + references[:mentioned_users_ids] = refs.mentioned_user_ids.presence + references[:mentioned_groups_ids] = refs.mentioned_group_ids.presence + references[:mentioned_projects_ids] = refs.mentioned_project_ids.presence # One retry is enough as next time `model_user_mention` should return the existing mention record, # that threw the `ActiveRecord::RecordNotUnique` exception in first place. diff --git a/app/presenters/blob_presenter.rb b/app/presenters/blob_presenter.rb index 56dd056b9bc..ecc16e2840c 100644 --- a/app/presenters/blob_presenter.rb +++ b/app/presenters/blob_presenter.rb @@ -26,6 +26,10 @@ class BlobPresenter < Gitlab::View::Presenter::Delegated highlight(plain: false) end + def raw_plain_data + blob.data unless blob.binary? + end + def web_url url_helpers.project_blob_url(project, ref_qualified_path) end diff --git a/app/presenters/snippet_blob_presenter.rb b/app/presenters/snippet_blob_presenter.rb index e9c710e4a0f..0003a13a7bc 100644 --- a/app/presenters/snippet_blob_presenter.rb +++ b/app/presenters/snippet_blob_presenter.rb @@ -17,6 +17,10 @@ class SnippetBlobPresenter < BlobPresenter snippet_blob_raw_route end + def raw_plain_data + blob.data unless blob.binary? + end + private def snippet diff --git a/app/views/projects/pipelines/_with_tabs.html.haml b/app/views/projects/pipelines/_with_tabs.html.haml index e56a240c487..c1d48992500 100644 --- a/app/views/projects/pipelines/_with_tabs.html.haml +++ b/app/views/projects/pipelines/_with_tabs.html.haml @@ -78,7 +78,7 @@ = build_summary(build) #js-tab-dag.tab-pane - #js-pipeline-dag-vue{ data: { pipeline_project_path: @project.full_path, pipeline_iid: @pipeline.iid, empty_svg_path: image_path('illustrations/empty-state/empty-dag-md.svg'), about_dag_doc_path: help_page_path('ci/directed_acyclic_graph/index.md'), dag_doc_path: help_page_path('ci/yaml/README.md', anchor: 'needs')} } + #js-pipeline-dag-vue{ data: { pipeline_project_path: @project.full_path, pipeline_iid: @pipeline.iid, empty_svg_path: image_path('illustrations/empty-state/empty-dag-md.svg'), about_dag_doc_path: help_page_path('ci/directed_acyclic_graph/index.md'), dag_doc_path: help_page_path('ci/yaml/index.md', anchor: 'needs')} } #js-tab-tests.tab-pane #js-pipeline-tests-detail{ data: { summary_endpoint: summary_project_pipeline_tests_path(@project, @pipeline, format: :json), diff --git a/app/views/shared/_project_limit.html.haml b/app/views/shared/_project_limit.html.haml index 9110f5a7f31..90612ba623f 100644 --- a/app/views/shared/_project_limit.html.haml +++ b/app/views/shared/_project_limit.html.haml @@ -1,8 +1,10 @@ - if cookies[:hide_project_limit_message].blank? && !current_user.hide_project_limit && !current_user.can_create_project? && current_user.projects_limit > 0 - .project-limit-message.gl-alert.gl-alert-warning.gl-display-none.gl-sm-display-block - = _("You won't be able to create new projects because you have reached your project limit.") - - .float-right - = link_to _("Don't show again"), profile_path(user: {hide_project_limit: true}), method: :put, class: 'alert-link' - | - = link_to _('Remind later'), '#', class: 'hide-project-limit-message alert-link' + = render 'shared/global_alert', + variant: :warning, + dismissible: false, + alert_class: 'project-limit-message' do + .gl-alert-body + = _("You won't be able to create new projects because you have reached your project limit.") + .gl-alert-actions + = link_to _('Remind later'), '#', class: 'alert-link hide-project-limit-message btn gl-button btn-confirm' + = link_to _("Don't show again"), profile_path(user: {hide_project_limit: true}), method: :put, class: 'alert-link btn gl-button btn-default gl-ml-3' diff --git a/app/views/shared/milestones/_issuable.html.haml b/app/views/shared/milestones/_issuable.html.haml index 184904dd7ab..12380d4c34e 100644 --- a/app/views/shared/milestones/_issuable.html.haml +++ b/app/views/shared/milestones/_issuable.html.haml @@ -25,3 +25,5 @@ = link_to polymorphic_path(issuable_type_args, { milestone_title: @milestone.title, assignee_id: assignee.id, state: 'all' }), class: 'has-tooltip', title: _("Assigned to %{assignee_name}") % { assignee_name: assignee.name }, data: { container: 'body' } do - image_tag(avatar_icon_for_user(assignee, 16), class: "avatar s16", alt: '') + + = render_if_exists "shared/milestones/issuable_weight", issuable: issuable diff --git a/app/views/shared/milestones/_issuables.html.haml b/app/views/shared/milestones/_issuables.html.haml index 9147e1c50e3..460ddd0897c 100644 --- a/app/views/shared/milestones/_issuables.html.haml +++ b/app/views/shared/milestones/_issuables.html.haml @@ -4,11 +4,15 @@ .card .card-header{ class: panel_class } - .title - = title - - if show_counter - .counter - = number_with_delimiter(issuables.length) + .header.gl-mb-2 + .title + = title + .issuable-count-weight.gl-ml-3 + - if show_counter + %span.counter + = sprite_icon('issues', css_class: 'gl-vertical-align-text-bottom') + = number_with_delimiter(issuables.length) + = render_if_exists "shared/milestones/issuables_weight", issuables: issuables - class_prefix = dom_class(issuables).pluralize %ul{ class: "content-list milestone-#{class_prefix}-list", id: "#{class_prefix}-list-#{id}" } diff --git a/config/feature_flags/development/gitlab_experiment_middleware.yml b/config/feature_flags/development/gitlab_experiment_middleware.yml new file mode 100644 index 00000000000..76f8a36812d --- /dev/null +++ b/config/feature_flags/development/gitlab_experiment_middleware.yml @@ -0,0 +1,8 @@ +--- +name: gitlab_experiment_middleware +introduced_by_url: +rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/323643 +milestone: '14.1' +type: development +group: group::adoption +default_enabled: false diff --git a/config/initializers/0_post_deployment_migrations.rb b/config/initializers/0_migration_paths_additional.rb similarity index 62% rename from config/initializers/0_post_deployment_migrations.rb rename to config/initializers/0_migration_paths_additional.rb index dabb82c8525..bf0c36e9bb6 100644 --- a/config/initializers/0_post_deployment_migrations.rb +++ b/config/initializers/0_migration_paths_additional.rb @@ -1,5 +1,8 @@ # frozen_string_literal: true +# Because we use Gitlab::Database, which in turn uses prepend_mod_with, +# we need this intializer to be after config/initializers/0_inject_enterprise_edition_module.rb. + # Post deployment migrations are included by default. This file must be loaded # before other initializers as Rails may otherwise memoize a list of migrations # excluding the post deployment migrations. diff --git a/config/initializers/check_decomposition_database_config.rb b/config/initializers/check_decomposition_database_config.rb new file mode 100644 index 00000000000..f32c72efa75 --- /dev/null +++ b/config/initializers/check_decomposition_database_config.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +ci_db_config = Gitlab::Application.config.database_configuration[Rails.env]["ci"] + +if ci_db_config.present? + raise "migrations_paths setting for ci database must be `db/ci_migrate`" unless ci_db_config["migrations_paths"] == 'db/ci_migrate' +end diff --git a/config/initializers/gitlab_experiment.rb b/config/initializers/gitlab_experiment.rb index 055979bb66b..39131e11260 100644 --- a/config/initializers/gitlab_experiment.rb +++ b/config/initializers/gitlab_experiment.rb @@ -2,16 +2,22 @@ Gitlab::Experiment.configure do |config| config.base_class = 'ApplicationExperiment' + config.mount_at = '/-/experiment' config.cache = Gitlab::Experiment::Cache::RedisHashStore.new( pool: ->(&block) { Gitlab::Redis::SharedState.with { |redis| block.call(redis) } } ) +end - # TODO: This will be deprecated as of v0.6.0, but needs to stay intact for - # actively running experiments until a versioning concept is put in place to - # enable migrating into the new SHA2 strategy. - config.context_hash_strategy = lambda do |source, seed| - source = source.keys + source.values if source.is_a?(Hash) - data = Array(source).map { |v| (v.respond_to?(:to_global_id) ? v.to_global_id : v).to_s } - Digest::MD5.hexdigest(data.unshift(seed).join('|')) +# TODO: This shim should be removed after the feature flag is rolled out, as +# it only exists to facilitate the feature flag control of the behavior. +module Gitlab::Experiment::MiddlewareWithFeatureFlags + attr_reader :app + + def call(env) + return app.call(env) unless Feature.enabled?(:gitlab_experiment_middleware) + + super end end + +Gitlab::Experiment::Middleware.prepend(Gitlab::Experiment::MiddlewareWithFeatureFlags) diff --git a/db/ci_migrate/20210617101848_create_ci_instance_variables_on_ci.rb b/db/ci_migrate/20210617101848_create_ci_instance_variables_on_ci.rb new file mode 100644 index 00000000000..7274e6bcdf2 --- /dev/null +++ b/db/ci_migrate/20210617101848_create_ci_instance_variables_on_ci.rb @@ -0,0 +1,31 @@ +# frozen_string_literal: true + +class CreateCiInstanceVariablesOnCi < ActiveRecord::Migration[6.1] + include Gitlab::Database::MigrationHelpers + + disable_ddl_transaction! + + def up + unless table_exists?(:ci_instance_variables) + create_table :ci_instance_variables do |t| + t.integer :variable_type, null: false, limit: 2, default: 1 + t.boolean :masked, default: false, allow_null: false + t.boolean :protected, default: false, allow_null: false + t.text :key, null: false + t.text :encrypted_value + t.text :encrypted_value_iv + + t.index [:key], name: 'index_ci_instance_variables_on_key', unique: true, using: :btree + end + end + + add_text_limit(:ci_instance_variables, :key, 255) + # Use constraint_name generated from db/migrate/20200625193358_increase_size_on_instance_level_variable_values.rb + add_text_limit(:ci_instance_variables, :encrypted_value, 13_579, constraint_name: 'check_956afd70f1') + add_text_limit(:ci_instance_variables, :encrypted_value_iv, 255) + end + + def down + drop_table :ci_instance_variables + end +end diff --git a/db/ci_structure.sql b/db/ci_structure.sql new file mode 100644 index 00000000000..16e2d25e507 --- /dev/null +++ b/db/ci_structure.sql @@ -0,0 +1,121 @@ +SET statement_timeout = 0; +SET lock_timeout = 0; +SET idle_in_transaction_session_timeout = 0; +SET client_encoding = 'UTF8'; +SET standard_conforming_strings = on; +SELECT pg_catalog.set_config('search_path', '', false); +SET check_function_bodies = false; +SET xmloption = content; +SET client_min_messages = warning; +SET row_security = off; + +SET default_tablespace = ''; + +SET default_table_access_method = heap; + +-- +-- Name: ar_internal_metadata; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.ar_internal_metadata ( + key character varying NOT NULL, + value character varying, + created_at timestamp(6) without time zone NOT NULL, + updated_at timestamp(6) without time zone NOT NULL +); + + +-- +-- Name: ci_instance_variables; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.ci_instance_variables ( + id bigint NOT NULL, + variable_type smallint DEFAULT 1 NOT NULL, + masked boolean DEFAULT false, + protected boolean DEFAULT false, + key text NOT NULL, + encrypted_value text, + encrypted_value_iv text, + CONSTRAINT check_07a45a5bcb CHECK ((char_length(encrypted_value_iv) <= 255)), + CONSTRAINT check_5aede12208 CHECK ((char_length(key) <= 255)), + CONSTRAINT check_956afd70f1 CHECK ((char_length(encrypted_value) <= 13579)) +); + + +-- +-- Name: ci_instance_variables_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.ci_instance_variables_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: ci_instance_variables_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.ci_instance_variables_id_seq OWNED BY public.ci_instance_variables.id; + + +-- +-- Name: schema_migrations; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.schema_migrations ( + version character varying NOT NULL +); + + +-- +-- Name: ci_instance_variables id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.ci_instance_variables ALTER COLUMN id SET DEFAULT nextval('public.ci_instance_variables_id_seq'::regclass); + + +-- +-- Name: ar_internal_metadata ar_internal_metadata_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.ar_internal_metadata + ADD CONSTRAINT ar_internal_metadata_pkey PRIMARY KEY (key); + + +-- +-- Name: ci_instance_variables ci_instance_variables_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.ci_instance_variables + ADD CONSTRAINT ci_instance_variables_pkey PRIMARY KEY (id); + + +-- +-- Name: schema_migrations schema_migrations_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.schema_migrations + ADD CONSTRAINT schema_migrations_pkey PRIMARY KEY (version); + + +-- +-- Name: index_ci_instance_variables_on_key; Type: INDEX; Schema: public; Owner: - +-- + +CREATE UNIQUE INDEX index_ci_instance_variables_on_key ON public.ci_instance_variables USING btree (key); + + +-- +-- PostgreSQL database dump complete +-- + +SET search_path TO "$user", public; + +INSERT INTO "schema_migrations" (version) VALUES +('20210617101848'); + + diff --git a/doc/administration/audit_events.md b/doc/administration/audit_events.md index f0c4d947668..7fab424ac93 100644 --- a/doc/administration/audit_events.md +++ b/doc/administration/audit_events.md @@ -120,6 +120,7 @@ From there, you can see the following actions: - Project access token was successfully created or revoked ([Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/230007) in GitLab 13.9) - Failed attempt to create or revoke a project access token ([Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/230007) in GitLab 13.9) - When default branch changes for a project ([Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/52339) in GitLab 13.9) +- Created, updated, or deleted DAST profiles, DAST scanner profiles, and DAST site profiles ([Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/217872)) Project events can also be accessed via the [Project Audit Events API](../api/audit_events.md#project-audit-events). diff --git a/doc/administration/instance_limits.md b/doc/administration/instance_limits.md index f230f7278bb..300c107abc8 100644 --- a/doc/administration/instance_limits.md +++ b/doc/administration/instance_limits.md @@ -192,7 +192,7 @@ The number of pipelines that can be created in a single push is 4. This is to prevent the accidental creation of pipelines when `git push --all` or `git push --mirror` is used. -Read more in the [CI documentation](../ci/yaml/README.md#processing-git-pushes). +Read more in the [CI documentation](../ci/yaml/index.md#processing-git-pushes). ## Retention of activity history @@ -407,7 +407,7 @@ Plan.default.actual_limits.update!(ci_instance_level_variables: 30) > [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/37226) in GitLab 13.3. -Job artifacts defined with [`artifacts:reports`](../ci/yaml/README.md#artifactsreports) +Job artifacts defined with [`artifacts:reports`](../ci/yaml/index.md#artifactsreports) that are uploaded by the runner are rejected if the file size exceeds the maximum file size limit. The limit is determined by comparing the project's [maximum artifact size setting](../user/admin_area/settings/continuous_integration.md#maximum-artifacts-size) @@ -576,7 +576,7 @@ prevent any more changes from rendering. For more information about these limits Reports that go over the 20 MB limit won't be loaded. Affected reports: - [Merge request security reports](../user/project/merge_requests/testing_and_reports_in_merge_requests.md#security-reports) -- [CI/CD parameter `artifacts:expose_as`](../ci/yaml/README.md#artifactsexpose_as) +- [CI/CD parameter `artifacts:expose_as`](../ci/yaml/index.md#artifactsexpose_as) - [Unit test reports](../ci/unit_test_reports.md) ## Advanced Search limits diff --git a/doc/administration/job_artifacts.md b/doc/administration/job_artifacts.md index 99eb1395503..3b1d253b4b6 100644 --- a/doc/administration/job_artifacts.md +++ b/doc/administration/job_artifacts.md @@ -42,10 +42,10 @@ To disable artifacts site-wide, follow the steps below. GitLab Runner can upload an archive containing the job artifacts to GitLab. By default, this is done when the job succeeds, but can also be done on failure, or always, via the -[`artifacts:when`](../ci/yaml/README.md#artifactswhen) parameter. +[`artifacts:when`](../ci/yaml/index.md#artifactswhen) parameter. Most artifacts are compressed by GitLab Runner before being sent to the coordinator. The exception to this is -[reports artifacts](../ci/yaml/README.md#artifactsreports), which are compressed after uploading. +[reports artifacts](../ci/yaml/index.md#artifactsreports), which are compressed after uploading. ### Using local storage @@ -326,7 +326,7 @@ To migrate back to local storage: ## Expiring artifacts -If [`artifacts:expire_in`](../ci/yaml/README.md#artifactsexpire_in) is used to set +If [`artifacts:expire_in`](../ci/yaml/index.md#artifactsexpire_in) is used to set an expiry for the artifacts, they are marked for deletion right after that date passes. Otherwise, they expire per the [default artifacts expiration setting](../user/admin_area/settings/continuous_integration.md). diff --git a/doc/administration/job_logs.md b/doc/administration/job_logs.md index 510da68442c..d42444b4ec2 100644 --- a/doc/administration/job_logs.md +++ b/doc/administration/job_logs.md @@ -108,7 +108,7 @@ See "Phase 4: uploading" in [Data flow](#data-flow) to learn about the process. If you want to avoid any local disk usage for job logs, you can do so using one of the following options: -- Enable the [beta incremental logging](#incremental-logging-architecture) feature. +- Enable the [incremental logging](#incremental-logging-architecture) feature. - Set the [job logs location](#changing-the-job-logs-local-location) to an NFS drive. @@ -140,7 +140,7 @@ For more information, see [delete references to missing artifacts](raketasks/che > - [Recommended for production use with AWS S3](https://gitlab.com/gitlab-org/gitlab/-/issues/273498) in GitLab 13.7. > - To use in GitLab self-managed instances, ask a GitLab administrator to [enable it](#enable-or-disable-incremental-logging). **(FREE SELF)** -Job logs are sent from the GitLab Runner in chunks and cached temporarily on disk +By default job logs are sent from the GitLab Runner in chunks and cached temporarily on disk in `/var/opt/gitlab/gitlab-ci/builds` by Omnibus GitLab. After the job completes, a background job archives the job log. The log is moved to `/var/opt/gitlab/gitlab-rails/shared/artifacts/` by default, or to object storage if configured. @@ -150,7 +150,7 @@ server, these two locations on the filesystem have to be shared using NFS. To eliminate both filesystem requirements: -- Enable the incremental logging feature, which uses Redis instead of disk space for temporary caching of job logs. +- [Enable the incremental logging feature](#enable-or-disable-incremental-logging), which uses Redis instead of disk space for temporary caching of job logs. - Configure [object storage](job_artifacts.md#object-storage-settings) for storing archived job logs. ### Technical details @@ -185,7 +185,7 @@ Here is the detailed data flow: ### Enable or disable incremental logging **(FREE SELF)** -Incremental logging is under development, but ready for production use. It is +Incremental logging is under development, but [ready for production use as of GitLab 13.6](https://gitlab.com/groups/gitlab-org/-/epics/4275). It is deployed behind a feature flag that is **disabled by default**. [GitLab administrators with access to the GitLab Rails console](feature_flags.md) can enable it. diff --git a/doc/administration/object_storage.md b/doc/administration/object_storage.md index f1025bd1846..5e1a2efbb4d 100644 --- a/doc/administration/object_storage.md +++ b/doc/administration/object_storage.md @@ -591,12 +591,6 @@ with the Fog library that GitLab uses. Symptoms include an error in `production. 411 Length Required ``` -### Incremental logging is required for CI to use object storage - -If you configure GitLab to use object storage for CI logs and artifacts, -you can avoid [local disk usage for job logs](job_logs.md#data-flow) by enabling -[beta incremental logging](job_logs.md#incremental-logging-architecture). - ### Proxy Download Clients can download files in object storage by receiving a pre-signed, time-limited URL, diff --git a/doc/api/commits.md b/doc/api/commits.md index 12549d3e538..78e0ae00cdb 100644 --- a/doc/api/commits.md +++ b/doc/api/commits.md @@ -638,8 +638,8 @@ GET /projects/:id/repository/commits/:sha/statuses | `id` | integer/string | yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user | `sha` | string | yes | The commit SHA | `ref` | string | no | The name of a repository branch or tag or, if not given, the default branch -| `stage` | string | no | Filter by [build stage](../ci/yaml/README.md#stages), e.g., `test` -| `name` | string | no | Filter by [job name](../ci/yaml/README.md#job-keywords), e.g., `bundler:audit` +| `stage` | string | no | Filter by [build stage](../ci/yaml/index.md#stages), e.g., `test` +| `name` | string | no | Filter by [job name](../ci/yaml/index.md#job-keywords), e.g., `bundler:audit` | `all` | boolean | no | Return all statuses, not only the latest ones ```shell diff --git a/doc/api/graphql/reference/index.md b/doc/api/graphql/reference/index.md index a9c61d8f6e3..2a1e7598033 100644 --- a/doc/api/graphql/reference/index.md +++ b/doc/api/graphql/reference/index.md @@ -3631,6 +3631,25 @@ Input type: `SecurityPolicyProjectAssignInput` | `clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. | | `errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. | +### `Mutation.securityPolicyProjectCreate` + +Input type: `SecurityPolicyProjectCreateInput` + +#### Arguments + +| Name | Type | Description | +| ---- | ---- | ----------- | +| `clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. | +| `projectPath` | [`ID!`](#id) | Full path of the project. | + +#### Fields + +| Name | Type | Description | +| ---- | ---- | ----------- | +| `clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. | +| `errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. | +| `project` | [`Project`](#project) | Security Policy Project that was created. | + ### `Mutation.terraformStateDelete` Input type: `TerraformStateDeleteInput` @@ -12240,6 +12259,7 @@ Represents an asset link associated with a release. | Name | Type | Description | | ---- | ---- | ----------- | +| `directAssetPath` | [`String`](#string) | Relative path for the direct asset link. | | `directAssetUrl` | [`String`](#string) | Direct asset URL of the link. | | `external` | [`Boolean`](#boolean) | Indicates the link points to an external resource. | | `id` | [`ID!`](#id) | ID of the link. | @@ -12861,6 +12881,7 @@ Represents the snippet blob. | `path` | [`String`](#string) | Blob path. | | `plainData` | [`String`](#string) | Blob plain highlighted data. | | `rawPath` | [`String!`](#string) | Blob raw content endpoint path. | +| `rawPlainData` | [`String`](#string) | The raw content of the blob, if the blob is text data. | | `renderedAsText` | [`Boolean!`](#boolean) | Shows whether the blob is rendered as text. | | `richData` | [`String`](#string) | Blob highlighted data. | | `richViewer` | [`SnippetBlobViewer`](#snippetblobviewer) | Blob content rich viewer. | diff --git a/doc/api/job_artifacts.md b/doc/api/job_artifacts.md index 62ad9758a2b..156fda9acae 100644 --- a/doc/api/job_artifacts.md +++ b/doc/api/job_artifacts.md @@ -28,7 +28,7 @@ Example request using the `PRIVATE-TOKEN` header: curl --output artifacts.zip --header "PRIVATE-TOKEN: " "https://gitlab.example.com/api/v4/projects/1/jobs/42/artifacts" ``` -To use this in a [`script` definition](../ci/yaml/README.md#script) inside +To use this in a [`script` definition](../ci/yaml/index.md#script) inside `.gitlab-ci.yml` **(PREMIUM)**, you can use either: - The `JOB-TOKEN` header with the GitLab-provided `CI_JOB_TOKEN` variable. @@ -93,7 +93,7 @@ Example request using the `PRIVATE-TOKEN` header: curl --header "PRIVATE-TOKEN: " "https://gitlab.example.com/api/v4/projects/1/jobs/artifacts/main/download?job=test" ``` -To use this in a [`script` definition](../ci/yaml/README.md#script) inside +To use this in a [`script` definition](../ci/yaml/index.md#script) inside `.gitlab-ci.yml` **(PREMIUM)**, you can use either: - The `JOB-TOKEN` header with the GitLab-provided `CI_JOB_TOKEN` variable. diff --git a/doc/api/lint.md b/doc/api/lint.md index 57d11d15adc..a47bb028248 100644 --- a/doc/api/lint.md +++ b/doc/api/lint.md @@ -87,8 +87,8 @@ Example responses: > [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/29568) in GitLab 13.5. The CI lint returns an expanded version of the configuration. The expansion does not -work for CI configuration added with [`include: local`](../ci/yaml/README.md#includelocal), -or with [`extends:`](../ci/yaml/README.md#extends). +work for CI configuration added with [`include: local`](../ci/yaml/index.md#includelocal), +or with [`extends:`](../ci/yaml/index.md#extends). Example contents of a `.gitlab-ci.yml` passed to the CI Lint API with `include_merged_yaml` set as true: diff --git a/doc/api/templates/gitlab_ci_ymls.md b/doc/api/templates/gitlab_ci_ymls.md index 388556d354f..82abe598cf6 100644 --- a/doc/api/templates/gitlab_ci_ymls.md +++ b/doc/api/templates/gitlab_ci_ymls.md @@ -9,7 +9,7 @@ type: reference In GitLab, there is an API endpoint available to work with GitLab CI/CD YMLs. For more information on CI/CD pipeline configuration in GitLab, see the -[configuration reference documentation](../../ci/yaml/README.md). +[configuration reference documentation](../../ci/yaml/index.md). ## List GitLab CI YAML templates diff --git a/doc/ci/caching/index.md b/doc/ci/caching/index.md index b1f12a13f55..0ed1e978168 100644 --- a/doc/ci/caching/index.md +++ b/doc/ci/caching/index.md @@ -11,7 +11,7 @@ A cache is one or more files that a job downloads and saves. Subsequent jobs tha the same cache don't have to download the files again, so they execute more quickly. To learn how to define the cache in your `.gitlab-ci.yml` file, -see the [`cache` reference](../yaml/README.md#cache). +see the [`cache` reference](../yaml/index.md#cache). ## How cache is different from artifacts @@ -38,8 +38,8 @@ can't link to files outside it. - Subsequent jobs in later stages of the same pipeline can use artifacts. - Different projects cannot share artifacts. -Artifacts expire after 30 days unless you define an [expiration time](../yaml/README.md#artifactsexpire_in). -Use [dependencies](../yaml/README.md#dependencies) to control which jobs fetch the artifacts. +Artifacts expire after 30 days unless you define an [expiration time](../yaml/index.md#artifactsexpire_in). +Use [dependencies](../yaml/index.md#dependencies) to control which jobs fetch the artifacts. ## Good caching practices @@ -48,7 +48,7 @@ To ensure maximum availability of the cache, do one or more of the following: - [Tag your runners](../runners/configure_runners.md#use-tags-to-limit-the-number-of-jobs-using-the-runner) and use the tag on jobs that share the cache. - [Use runners that are only available to a particular project](../runners/runners_scope.md#prevent-a-specific-runner-from-being-enabled-for-other-projects). -- [Use a `key`](../yaml/README.md#cachekey) that fits your workflow. For example, +- [Use a `key`](../yaml/index.md#cachekey) that fits your workflow. For example, you can configure a different cache for each branch. For runners to work with caches efficiently, you must do one of the following: @@ -97,7 +97,7 @@ the fallback cache is fetched every time a cache is not found. > [Introduced](https://gitlab.com/gitlab-org/gitlab-runner/-/merge_requests/1534) in GitLab Runner 13.4. You can use the `$CI_COMMIT_REF_SLUG` [predefined variable](../variables/predefined_variables.md) -to specify your [`cache:key`](../yaml/README.md#cachekey). For example, if your +to specify your [`cache:key`](../yaml/index.md#cachekey). For example, if your `$CI_COMMIT_REF_SLUG` is `test`, you can set a job to download cache that's tagged with `test`. If a cache with this tag is not found, you can use `CACHE_FALLBACK_KEY` to @@ -134,7 +134,7 @@ job: ## Inherit global configuration, but override specific settings per job You can override cache settings without overwriting the global cache by using -[anchors](../yaml/README.md#anchors). For example, if you want to override the +[anchors](../yaml/index.md#anchors). For example, if you want to override the `policy` for one job: ```yaml @@ -154,7 +154,7 @@ job: policy: pull ``` -For more information, see [`cache: policy`](../yaml/README.md#cachepolicy). +For more information, see [`cache: policy`](../yaml/index.md#cachepolicy). ## Common use cases for caches @@ -212,7 +212,7 @@ cache: If your project uses [npm](https://www.npmjs.com/) to install Node.js dependencies, the following example defines `cache` globally so that all jobs inherit it. By default, npm stores cache data in the home folder (`~/.npm`). However, you -[can't cache things outside of the project directory](../yaml/README.md#cachepaths). +[can't cache things outside of the project directory](../yaml/index.md#cachepaths). Instead, tell npm to use `./.npm`, and cache it per-branch: ```yaml @@ -392,7 +392,7 @@ test: Caching is an optimization, but it isn't guaranteed to always work. You might need to regenerate cached files in each job that needs them. -After you define a [cache in `.gitlab-ci.yml`](../yaml/README.md#cache), +After you define a [cache in `.gitlab-ci.yml`](../yaml/index.md#cache), the availability of the cache depends on: - The runner's executor type. @@ -489,7 +489,7 @@ machines, it is a safe default. ## Clearing the cache -Runners use [cache](../yaml/README.md#cache) to speed up the execution +Runners use [cache](../yaml/index.md#cache) to speed up the execution of your jobs by reusing existing data. This can sometimes lead to inconsistent behavior. diff --git a/doc/ci/chatops/index.md b/doc/ci/chatops/index.md index 309aa34d44b..c277d12cb49 100644 --- a/doc/ci/chatops/index.md +++ b/doc/ci/chatops/index.md @@ -32,7 +32,7 @@ to the job: - `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 +to a corresponding job in [`.gitlab-ci.yml`](../yaml/index.md). If a matching job is found on the default branch, a pipeline containing only that job is scheduled. After the job completes: diff --git a/doc/ci/cloud_deployment/index.md b/doc/ci/cloud_deployment/index.md index 7c865be1f2b..201c9072f81 100644 --- a/doc/ci/cloud_deployment/index.md +++ b/doc/ci/cloud_deployment/index.md @@ -91,7 +91,7 @@ path to point to your ECR image. > - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/207962) in GitLab 12.9. > - The `Deploy-ECS.gitlab-ci.yml` template was [moved](https://gitlab.com/gitlab-org/gitlab/-/issues/220821) to `AWS/Deploy-ECS.gitlab-ci.yml` in GitLab 13.2. -GitLab provides a series of [CI templates that you can include in your project](../yaml/README.md#include). +GitLab provides a series of [CI templates that you can include in your project](../yaml/index.md#include). To automate deployments of your application to your [Amazon Elastic Container Service](https://aws.amazon.com/ecs/) (AWS ECS) cluster, you can `include` the `AWS/Deploy-ECS.gitlab-ci.yml` template in your `.gitlab-ci.yml` file. @@ -231,7 +231,7 @@ pass three JSON input objects, based on existing templates: - [Template for the _Create stack_ step on AWS](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/template-anatomy.html). - Template for the _Push to S3_ step. Note that `source` is where a preceding `build` job built - your application, exporting the build through [`artifacts:paths`](../yaml/README.md#artifactspaths): + your application, exporting the build through [`artifacts:paths`](../yaml/index.md#artifactspaths): ```json { diff --git a/doc/ci/directed_acyclic_graph/index.md b/doc/ci/directed_acyclic_graph/index.md index e9725a29fc7..d965d4b83f9 100644 --- a/doc/ci/directed_acyclic_graph/index.md +++ b/doc/ci/directed_acyclic_graph/index.md @@ -66,9 +66,9 @@ as quickly as possible. ## Usage -Relationships are defined between jobs using the [`needs:` keyword](../yaml/README.md#needs). +Relationships are defined between jobs using the [`needs:` keyword](../yaml/index.md#needs). -Note that `needs:` also works with the [parallel](../yaml/README.md#parallel) keyword, +Note that `needs:` also works with the [parallel](../yaml/index.md#parallel) keyword, giving you powerful options for parallelization within your pipeline. ## Limitations @@ -76,7 +76,7 @@ giving you powerful options for parallelization within your pipeline. A directed acyclic graph is a complicated feature, and as of the initial MVC there are certain use cases that you may need to work around. For more information: -- [`needs` requirements and limitations](../yaml/README.md#requirements-and-limitations). +- [`needs` requirements and limitations](../yaml/index.md#requirements-and-limitations). - Related epic [tracking planned improvements](https://gitlab.com/groups/gitlab-org/-/epics/1716). ## Needs Visualization diff --git a/doc/ci/docker/using_docker_build.md b/doc/ci/docker/using_docker_build.md index 4b7a6b114eb..fb45d8f295c 100644 --- a/doc/ci/docker/using_docker_build.md +++ b/doc/ci/docker/using_docker_build.md @@ -577,7 +577,7 @@ don't work because a fresh Docker daemon is started with the service. ### Option 1: Run `docker login` -In [`before_script`](../yaml/README.md#before_script), run `docker +In [`before_script`](../yaml/index.md#before_script), run `docker login`: ```yaml @@ -682,10 +682,10 @@ There are multiple ways to define this authentication: - In [`pre_build_script`](https://docs.gitlab.com/runner/configuration/advanced-configuration.html#the-runners-section) in the runner configuration file. -- In [`before_script`](../yaml/README.md#before_script). -- In [`script`](../yaml/README.md#script). +- In [`before_script`](../yaml/index.md#before_script). +- In [`script`](../yaml/index.md#script). -The following example shows [`before_script`](../yaml/README.md#before_script). +The following example shows [`before_script`](../yaml/index.md#before_script). The same commands apply for any solution you implement. ```yaml @@ -798,7 +798,7 @@ which can be avoided if a different driver is used, for example `overlay2`. ### Use the OverlayFS driver per project You can enable the driver for each project individually by using the `DOCKER_DRIVER` -[CI/CD variable](../yaml/README.md#variables) in `.gitlab-ci.yml`: +[CI/CD variable](../yaml/index.md#variables) in `.gitlab-ci.yml`: ```yaml variables: diff --git a/doc/ci/docker/using_docker_images.md b/doc/ci/docker/using_docker_images.md index 47c8453dcca..c2991ce66f9 100644 --- a/doc/ci/docker/using_docker_images.md +++ b/doc/ci/docker/using_docker_images.md @@ -153,9 +153,9 @@ CI/CD jobs: from `Dockerfile` that may be overridden in the `.gitlab-ci.yml` file. 1. The runner attaches itself to a running container. 1. The runner prepares a script (the combination of - [`before_script`](../yaml/README.md#before_script), - [`script`](../yaml/README.md#script), - and [`after_script`](../yaml/README.md#after_script)). + [`before_script`](../yaml/index.md#before_script), + [`script`](../yaml/index.md#script), + and [`after_script`](../yaml/index.md#after_script)). 1. The runner sends the script to the container's shell `stdin` and receives the output. diff --git a/doc/ci/enable_or_disable_ci.md b/doc/ci/enable_or_disable_ci.md index 95f1fa9fb33..341727f0f5d 100644 --- a/doc/ci/enable_or_disable_ci.md +++ b/doc/ci/enable_or_disable_ci.md @@ -9,7 +9,7 @@ type: howto To effectively use GitLab CI/CD, you need: -- A valid [`.gitlab-ci.yml`](yaml/README.md) file present at the root directory +- A valid [`.gitlab-ci.yml`](yaml/index.md) file present at the root directory of your project. - A [runner](runners/index.md) properly set up. diff --git a/doc/ci/environments/deployment_safety.md b/doc/ci/environments/deployment_safety.md index 46141e2426b..f8aa179b881 100644 --- a/doc/ci/environments/deployment_safety.md +++ b/doc/ci/environments/deployment_safety.md @@ -35,7 +35,7 @@ Pipeline jobs in GitLab CI/CD run in parallel, so it's possible that two deploym jobs in two different pipelines attempt to deploy to the same environment at the same time. This is not desired behavior as deployments should happen sequentially. -You can ensure only one deployment job runs at a time with the [`resource_group` keyword](../yaml/README.md#resource_group) in your `.gitlab-ci.yml`. +You can ensure only one deployment job runs at a time with the [`resource_group` keyword](../yaml/index.md#resource_group) in your `.gitlab-ci.yml`. For example: @@ -59,7 +59,7 @@ The improved pipeline flow **after** using the resource group: 1. `deploy` job in Pipeline-A finishes. 1. `deploy` job in Pipeline-B starts running. -For more information, see [`resource_group` keyword in `.gitlab-ci.yml`](../yaml/README.md#resource_group). +For more information, see [`resource_group` keyword in `.gitlab-ci.yml`](../yaml/index.md#resource_group). ## Skip outdated deployment jobs diff --git a/doc/ci/environments/index.md b/doc/ci/environments/index.md index c9b5690ea41..903d5c8e647 100644 --- a/doc/ci/environments/index.md +++ b/doc/ci/environments/index.md @@ -10,7 +10,7 @@ disqus_identifier: 'https://docs.gitlab.com/ee/ci/environments.html' Environments describe where code is deployed. -Each time [GitLab CI/CD](../yaml/README.md) deploys a version of code to an environment, +Each time [GitLab CI/CD](../yaml/index.md) deploys a version of code to an environment, a deployment is created. GitLab: @@ -84,7 +84,7 @@ When the job runs, the environment and deployment are created. NOTE: Some characters cannot be used in environment names. For more information about the `environment` keywords, see -[the `.gitlab-ci.yml` keyword reference](../yaml/README.md#environment). +[the `.gitlab-ci.yml` keyword reference](../yaml/index.md#environment). ### Create a dynamic environment @@ -107,7 +107,7 @@ deploy_review: In this example: -- The `name` is `review/$CI_COMMIT_REF_NAME`. Because the [environment name](../yaml/README.md#environmentname) +- The `name` is `review/$CI_COMMIT_REF_NAME`. Because the [environment name](../yaml/index.md#environmentname) can contain slashes (`/`), you can use this pattern to distinguish between dynamic and static environments. - For the `url`, you could use `$CI_COMMIT_REF_NAME`, but because this value may contain a `/` or other characters that would not be valid in a domain name or URL, @@ -119,7 +119,7 @@ However, when you use this format, you can [group similar environments](#group-s NOTE: Some variables cannot be used as environment names or URLs. For more information about the `environment` keywords, see -[the `.gitlab-ci.yml` keyword reference](../yaml/README.md#environment). +[the `.gitlab-ci.yml` keyword reference](../yaml/index.md#environment). ## Deployment tier of environments @@ -141,8 +141,8 @@ you can use tiers: | `development` | Dev, [Review apps](../review_apps/index.md), Trunk | | `other` | | -By default, GitLab assumes a tier based on [the environment name](../yaml/README.md#environmentname). -Instead, you can use the [`deployment_tier` keyword](../yaml/README.md#environmentdeployment_tier) to specify a tier. +By default, GitLab assumes a tier based on [the environment name](../yaml/index.md#environmentname). +Instead, you can use the [`deployment_tier` keyword](../yaml/index.md#environmentdeployment_tier) to specify a tier. ## Configure manual deployments @@ -250,7 +250,7 @@ GitLab supports the [dotenv (`.env`)](https://github.com/bkeepers/dotenv) file f and expands the `environment:url` value with variables defined in the `.env` file. To use this feature, specify the -[`artifacts:reports:dotenv`](../yaml/README.md#artifactsreportsdotenv) keyword in `.gitlab-ci.yml`. +[`artifacts:reports:dotenv`](../yaml/index.md#artifactsreportsdotenv) keyword in `.gitlab-ci.yml`. For an overview, see [Set dynamic URLs after a job finished](https://youtu.be/70jDXtOf4Ig). @@ -334,7 +334,7 @@ To retry or rollback a deployment: ### Environment URL -The [environment URL](../yaml/README.md#environmenturl) is displayed in a few +The [environment URL](../yaml/index.md#environmenturl) is displayed in a few places in GitLab: - In a merge request as a link: @@ -364,7 +364,7 @@ When you stop an environment: - On the **Environments** page, it moves from the list of **Available** environments to the list of **Stopped** environments. -- An [`on_stop` action](../yaml/README.md#environmenton_stop), if defined, is executed. +- An [`on_stop` action](../yaml/index.md#environmenton_stop), if defined, is executed. Dynamic environments stop automatically when their associated branch is deleted. @@ -400,8 +400,8 @@ stop_review: when: manual ``` -Both jobs must have the same [`rules`](../yaml/README.md#only--except) -or [`only/except`](../yaml/README.md#only--except) configuration. Otherwise, +Both jobs must have the same [`rules`](../yaml/index.md#only--except) +or [`only/except`](../yaml/index.md#only--except) configuration. Otherwise, the `stop_review` job might not be included in all pipelines that include the `deploy_review` job, and you cannot trigger `action: stop` to stop the environment automatically. @@ -413,7 +413,7 @@ set the [`GIT_STRATEGY`](../runners/configure_runners.md#git-strategy) to `none` `stop_review` job. Then the [runner](https://docs.gitlab.com/runner/) doesn't try to check out the code after the branch is deleted. -Read more in the [`.gitlab-ci.yml` reference](../yaml/README.md#environmenton_stop). +Read more in the [`.gitlab-ci.yml` reference](../yaml/index.md#environmenton_stop). #### Stop an environment after a certain time period @@ -421,7 +421,7 @@ Read more in the [`.gitlab-ci.yml` reference](../yaml/README.md#environmenton_st You can set environments to stop automatically after a certain time period. -In your `.gitlab-ci.yml` file, specify the [`environment:auto_stop_in`](../yaml/README.md#environmentauto_stop_in) +In your `.gitlab-ci.yml` file, specify the [`environment:auto_stop_in`](../yaml/index.md#environmentauto_stop_in) keyword. You can specify a human-friendly date as the value, such as `1 hour and 30 minutes` or `1 day`. After the time period passes, GitLab automatically triggers a job to stop the environment. @@ -767,7 +767,7 @@ To ensure the `action: stop` can always run when needed, you can: when: manual ``` -- Add a [`needs`](../yaml/README.md#needs) entry to the `action: stop` job so the +- Add a [`needs`](../yaml/index.md#needs) entry to the `action: stop` job so the job can start out of stage order: ```yaml diff --git a/doc/ci/examples/end_to_end_testing_webdriverio/index.md b/doc/ci/examples/end_to_end_testing_webdriverio/index.md index be096cdcf6c..7a6d692cd43 100644 --- a/doc/ci/examples/end_to_end_testing_webdriverio/index.md +++ b/doc/ci/examples/end_to_end_testing_webdriverio/index.md @@ -146,10 +146,10 @@ new browser window interacting with your app as you specified. Which brings us to the exciting part: how do we run this in GitLab CI/CD? There are two things we need to do for this: -1. Set up [CI/CD jobs](../../yaml/README.md) that actually have a browser available. +1. Set up [CI/CD jobs](../../yaml/index.md) that actually have a browser available. 1. Update our WebdriverIO configuration to use those browsers to visit the review apps. -For the scope of this article, we've defined an additional [CI/CD stage](../../yaml/README.md#stages) +For the scope of this article, we've defined an additional [CI/CD stage](../../yaml/index.md#stages) `confidence-check` that is executed _after_ the stage that deploys the review app. It uses the `node:latest` [Docker image](../../docker/using_docker_images.md). However, WebdriverIO fires up actual browsers to interact with your application, so we need to install and run them. @@ -255,5 +255,5 @@ production project, see: There's plenty more that WebdriverIO can do. For example, you can configure a [`screenshotPath`](http://v4.webdriver.io/guide/getstarted/configuration.html#screenshotPath) to tell WebdriverIO to take a screenshot when tests are failing. Then tell GitLab CI/CD to store those -[artifacts](../../yaml/README.md#artifacts), and you'll be able to see what went +[artifacts](../../yaml/index.md#artifacts), and you'll be able to see what went wrong within GitLab. 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 dcf43c0df75..c511839b3e4 100644 --- a/doc/ci/examples/laravel_with_gitlab_and_envoy/index.md +++ b/doc/ci/examples/laravel_with_gitlab_and_envoy/index.md @@ -548,7 +548,7 @@ If you wish to test your app with different PHP versions and [database managemen #### CI/CD variables -GitLab CI/CD allows us to use [CI/CD variables](../../yaml/README.md#variables) in our jobs. +GitLab CI/CD allows us to use [CI/CD variables](../../yaml/index.md#variables) in our jobs. We defined MySQL as our database management system, which comes with a superuser root created by default. So we should adjust the configuration of MySQL instance by defining `MYSQL_DATABASE` variable as our database name and `MYSQL_ROOT_PASSWORD` variable as the password of `root`. @@ -567,7 +567,7 @@ variables: #### Unit Test as the first job -We defined the required shell scripts as an array of the [script](../../yaml/README.md#script) keyword to be executed when running `unit_test` job. +We defined the required shell scripts as an array of the [script](../../yaml/index.md#script) keyword to be executed when running `unit_test` job. These scripts are some Artisan commands to prepare the Laravel, and, at the end of the script, we'll run the tests by `PHPUnit`. @@ -593,7 +593,7 @@ To deploy our app with Envoy, we had to set up the `$SSH_PRIVATE_KEY` variable a 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. -The [environment](../../yaml/README.md#environment) keyword tells GitLab that this job deploys to the `production` environment. +The [environment](../../yaml/index.md#environment) keyword tells GitLab that this job deploys to the `production` environment. The `url` keyword is used to generate a link to our application on the GitLab Environments page. The `only` keyword tells GitLab CI/CD that the job should be executed only when the pipeline is building the `main` branch. Lastly, `when: manual` is used to turn the job from running automatically to a manual action. diff --git a/doc/ci/index.md b/doc/ci/index.md index 74b6feffc7f..1cd78f6d5ef 100644 --- a/doc/ci/index.md +++ b/doc/ci/index.md @@ -77,7 +77,7 @@ GitLab CI/CD supports numerous configuration options: | [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. | | [Optimize GitLab and GitLab Runner for large repositories](large_repositories/index.md) | Recommended strategies for handling large repositories. | -| [`.gitlab-ci.yml` full reference](yaml/README.md) | All the attributes you can use with GitLab CI/CD. | +| [`.gitlab-ci.yml` full reference](yaml/index.md) | All the attributes you can use with GitLab CI/CD. | Note that certain operations can only be performed according to the [user](../user/permissions.md#gitlab-cicd-permissions) and [job](../user/permissions.md#job-permissions) permissions. diff --git a/doc/ci/jobs/index.md b/doc/ci/jobs/index.md index 3ff3c0c10e9..3fe30c78d6a 100644 --- a/doc/ci/jobs/index.md +++ b/doc/ci/jobs/index.md @@ -11,7 +11,7 @@ Pipeline configuration begins with jobs. Jobs are the most fundamental element o Jobs are: - Defined with constraints stating under what conditions they should be executed. -- Top-level elements with an arbitrary name and must contain at least the [`script`](../yaml/README.md#script) clause. +- Top-level elements with an arbitrary name and must contain at least the [`script`](../yaml/index.md#script) clause. - Not limited in how many can be defined. For example: @@ -101,7 +101,7 @@ jobs. Click to expand them. ![Grouped pipelines](img/pipelines_grouped.png) -To create a group of jobs, in the [CI/CD pipeline configuration file](../yaml/README.md), +To create a group of jobs, in the [CI/CD pipeline configuration file](../yaml/index.md), separate each job name with a number and one of the following: - A slash (`/`), for example, `test 1/3`, `test 2/3`, `test 3/3`. @@ -168,7 +168,7 @@ for a single run of the manual job. > [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/21767) in GitLab 11.4. -When you do not want to run a job immediately, you can use the [`when:delayed`](../yaml/README.md#whendelayed) keyword to +When you do not want to run a job immediately, you can use the [`when:delayed`](../yaml/index.md#whendelayed) keyword to delay a job's execution for a certain period. This is especially useful for timed incremental rollout where new code is rolled out gradually. diff --git a/doc/ci/jobs/job_control.md b/doc/ci/jobs/job_control.md index cb5483e97a4..c0c4f256633 100644 --- a/doc/ci/jobs/job_control.md +++ b/doc/ci/jobs/job_control.md @@ -12,22 +12,22 @@ the status of variables, the pipeline type, and so on. To configure a job to be included or excluded from certain pipelines, you can use: -- [`rules`](../yaml/README.md#rules) -- [`only`](../yaml/README.md#only--except) -- [`except`](../yaml/README.md#only--except) +- [`rules`](../yaml/index.md#rules) +- [`only`](../yaml/index.md#only--except) +- [`except`](../yaml/index.md#only--except) -Use [`needs`](../yaml/README.md#needs) to configure a job to run as soon as the +Use [`needs`](../yaml/index.md#needs) to configure a job to run as soon as the earlier jobs it depends on finish running. ## Specify when jobs run with `rules` > [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/27863) in GitLab 12.3. -Use [`rules`](../yaml/README.md#rules) to include or exclude jobs in pipelines. +Use [`rules`](../yaml/index.md#rules) to include or exclude jobs in pipelines. Rules are evaluated in order until the first match. When a match is found, the job is either included or excluded from the pipeline, depending on the configuration. -See the [`rules`](../yaml/README.md#rules) reference for more details. +See the [`rules`](../yaml/index.md#rules) reference for more details. Future keyword improvements are being discussed in our [epic for improving `rules`](https://gitlab.com/groups/gitlab-org/-/epics/2783), where anyone can add suggestions or requests. @@ -150,7 +150,7 @@ causes duplicated pipelines. To avoid duplicate pipelines, you can: -- Use [`workflow`](../yaml/README.md#workflow) to specify which types of pipelines +- Use [`workflow`](../yaml/index.md#workflow) to specify which types of pipelines can run. - Rewrite the rules to run the job only in very specific cases, and avoid a final `when:` rule: @@ -179,7 +179,7 @@ job: ``` You should not include both push and merge request pipelines in the same job without -[`workflow:rules` that prevent duplicate pipelines](../yaml/README.md#switch-between-branch-pipelines-and-merge-request-pipelines): +[`workflow:rules` that prevent duplicate pipelines](../yaml/index.md#switch-between-branch-pipelines-and-merge-request-pipelines): ```yaml job: @@ -206,12 +206,12 @@ job-with-rules: For every change pushed to the branch, duplicate pipelines run. One branch pipeline runs a single job (`job-with-no-rules`), and one merge request pipeline runs the other job (`job-with-rules`). Jobs with no rules default -to [`except: merge_requests`](../yaml/README.md#only--except), so `job-with-no-rules` +to [`except: merge_requests`](../yaml/index.md#only--except), so `job-with-no-rules` runs in all cases except merge requests. ### Common `if` clauses for `rules` -For behavior similar to the [`only`/`except` keywords](../yaml/README.md#only--except), you can +For behavior similar to the [`only`/`except` keywords](../yaml/index.md#only--except), you can check the value of the `$CI_PIPELINE_SOURCE` variable: | Value | Description | @@ -222,7 +222,7 @@ check the value of the `$CI_PIPELINE_SOURCE` variable: | `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). | | `parent_pipeline` | For pipelines triggered by a [parent/child pipeline](../parent_child_pipelines.md) with `rules`. Use this pipeline source in the child pipeline configuration so that it can be triggered by the parent pipeline. | -| `pipeline` | For [multi-project pipelines](../multi_project_pipelines.md) created by [using the API with `CI_JOB_TOKEN`](../multi_project_pipelines.md#create-multi-project-pipelines-by-using-the-api), or the [`trigger`](../yaml/README.md#trigger) keyword. | +| `pipeline` | For [multi-project pipelines](../multi_project_pipelines.md) created by [using the API with `CI_JOB_TOKEN`](../multi_project_pipelines.md#create-multi-project-pipelines-by-using-the-api), or the [`trigger`](../yaml/index.md#trigger) keyword. | | `push` | For pipelines triggered by a `git push` event, including for branches and tags. | | `schedule` | For [scheduled pipelines](../pipelines/schedules.md). | | `trigger` | For pipelines created by using a [trigger token](../triggers/index.md#trigger-token). | @@ -292,7 +292,7 @@ You can use the `$` character for both variables and paths. For example, if the ## Specify when jobs run with `only` and `except` -You can use [`only`](../yaml/README.md#only--except) and [`except`](../yaml/README.md#only--except) +You can use [`only`](../yaml/index.md#only--except) and [`except`](../yaml/index.md#only--except) to control when to add jobs to pipelines. - Use `only` to define when a job runs. @@ -301,7 +301,7 @@ to control when to add jobs to pipelines. ### `only:refs` / `except:refs` examples `only` or `except` used without `refs` is the same as -[`only:refs` / `except/refs`](../yaml/README.md#onlyrefs--exceptrefs) +[`only:refs` / `except/refs`](../yaml/index.md#onlyrefs--exceptrefs) In the following example, `job` runs only for: @@ -334,7 +334,7 @@ except `main` and branches that start with `release/`. ### `only: variables` / `except: variables` examples -You can use [`except:variables`](../yaml/README.md#onlyvariables--exceptvariables) to exclude jobs based on a commit message: +You can use [`except:variables`](../yaml/index.md#onlyvariables--exceptvariables) to exclude jobs based on a commit message: ```yaml end-to-end: @@ -502,9 +502,9 @@ test: You can use [predefined CI/CD variables](../variables/predefined_variables.md) to choose which pipeline types jobs run in, with: -- [`rules`](../yaml/README.md#rules) -- [`only:variables`](../yaml/README.md#onlyvariables--exceptvariables) -- [`except:variables`](../yaml/README.md#onlyvariables--exceptvariables) +- [`rules`](../yaml/index.md#rules) +- [`only:variables`](../yaml/index.md#onlyvariables--exceptvariables) +- [`except:variables`](../yaml/index.md#onlyvariables--exceptvariables) The following table lists some of the variables that you can use, and the pipeline types the variables can control for: @@ -592,14 +592,14 @@ Feature.enable(:allow_unsafe_ruby_regexp) ## CI/CD variable expressions -> - [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/37397) in GitLab 10.7 for [the `only` and `except` CI keywords](../yaml/README.md#onlyvariables--exceptvariables) -> - [Expanded](https://gitlab.com/gitlab-org/gitlab/-/issues/27863) in GitLab 12.3 with [the `rules` keyword](../yaml/README.md#rules) +> - [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/37397) in GitLab 10.7 for [the `only` and `except` CI keywords](../yaml/index.md#onlyvariables--exceptvariables) +> - [Expanded](https://gitlab.com/gitlab-org/gitlab/-/issues/27863) in GitLab 12.3 with [the `rules` keyword](../yaml/index.md#rules) Use variable expressions to control which jobs are created in a pipeline after changes are pushed to GitLab. You can use variable expressions with: -- [`rules:if`](../yaml/README.md#rules). -- [`only:variables` and `except:variables`](../yaml/README.md#onlyvariables--exceptvariables). +- [`rules:if`](../yaml/index.md#rules). +- [`only:variables` and `except:variables`](../yaml/index.md#onlyvariables--exceptvariables). For example, with `rules:if`: diff --git a/doc/ci/lint.md b/doc/ci/lint.md index 3888a750d6a..746638442a7 100644 --- a/doc/ci/lint.md +++ b/doc/ci/lint.md @@ -20,7 +20,7 @@ in your project and click **CI lint**. ## Validate basic logic and syntax By default, the CI lint checks the syntax of your CI YAML configuration and also runs -some basic logical validations. Configuration added with the [`includes` keyword](yaml/README.md#include), +some basic logical validations. Configuration added with the [`includes` keyword](yaml/index.md#include), is also validated. To use the CI lint, paste a complete CI configuration (`.gitlab-ci.yml` for example) diff --git a/doc/ci/merge_request_pipelines/index.md b/doc/ci/merge_request_pipelines/index.md index a9a429292da..e710df4f397 100644 --- a/doc/ci/merge_request_pipelines/index.md +++ b/doc/ci/merge_request_pipelines/index.md @@ -39,13 +39,13 @@ To enable pipelines for merge requests: ## Configure pipelines for merge requests -To configure pipelines for merge requests, you must configure your [CI/CD configuration file](../yaml/README.md). +To configure pipelines for merge requests, you must configure your [CI/CD configuration file](../yaml/index.md). To do this, you can use [`rules`](#use-rules-to-run-pipelines-for-merge-requests) or [`only/except`](#use-only-or-except-to-run-pipelines-for-merge-requests). ### Use `rules` to run pipelines for merge requests GitLab recommends that you use the `rules` keyword, which is available in -[`workflow:rules` templates](../yaml/README.md#workflowrules-templates). +[`workflow:rules` templates](../yaml/index.md#workflowrules-templates). ### Use `only` or `except` to run pipelines for merge requests @@ -138,7 +138,7 @@ Instead, use the [`$CI_COMMIT_REF_NAME` predefined environment variable](../variables/predefined_variables.md) in combination with -[`only:variables`](../yaml/README.md#onlyvariables--exceptvariables) to +[`only:variables`](../yaml/index.md#onlyvariables--exceptvariables) to accomplish this behavior: ```yaml @@ -199,7 +199,7 @@ If you are seeing two pipelines when using `only/except`, please see the caveats related to using `only/except` above (or, consider moving to `rules`). In [GitLab 13.7](https://gitlab.com/gitlab-org/gitlab/-/issues/201845) and later, -you can add `workflow:rules` to [switch from branch pipelines to merge request pipelines](../yaml/README.md#switch-between-branch-pipelines-and-merge-request-pipelines). +you can add `workflow:rules` to [switch from branch pipelines to merge request pipelines](../yaml/index.md#switch-between-branch-pipelines-and-merge-request-pipelines). After a merge request is open on the branch, the pipeline switches to a merge request pipeline. ### Two pipelines created when pushing an invalid CI configuration file diff --git a/doc/ci/metrics_reports.md b/doc/ci/metrics_reports.md index 47236668e89..0b0226f428a 100644 --- a/doc/ci/metrics_reports.md +++ b/doc/ci/metrics_reports.md @@ -37,7 +37,7 @@ For an MR, the values of these metrics from the feature branch are compared to t ## How to set it up -Add a job that creates a [metrics report](yaml/README.md#artifactsreportsmetrics) (default filename: `metrics.txt`). The file should conform to the [OpenMetrics](https://openmetrics.io/) format. +Add a job that creates a [metrics report](yaml/index.md#artifactsreportsmetrics) (default filename: `metrics.txt`). The file should conform to the [OpenMetrics](https://openmetrics.io/) format. For example: diff --git a/doc/ci/migration/circleci.md b/doc/ci/migration/circleci.md index 28b467d07c6..968adf2e161 100644 --- a/doc/ci/migration/circleci.md +++ b/doc/ci/migration/circleci.md @@ -68,7 +68,7 @@ job1: ### Workflows -CircleCI determines the run order for jobs with `workflows`. This is also used to determine concurrent, sequential, scheduled, or manual runs. The equivalent function in GitLab CI/CD is called [stages](../yaml/README.md#stages). Jobs on the same stage run in parallel, and only run after previous stages complete. Execution of the next stage is skipped when a job fails by default, but this can be allowed to continue even [after a failed job](../yaml/README.md#allow_failure). +CircleCI determines the run order for jobs with `workflows`. This is also used to determine concurrent, sequential, scheduled, or manual runs. The equivalent function in GitLab CI/CD is called [stages](../yaml/index.md#stages). Jobs on the same stage run in parallel, and only run after previous stages complete. Execution of the next stage is skipped when a job fails by default, but this can be allowed to continue even [after a failed job](../yaml/index.md#allow_failure). See [the Pipeline Architecture Overview](../pipelines/pipeline_architectures.md) for guidance on different types of pipelines that you can use. Pipelines can be tailored to meet your needs, such as for a large complex project or a monorepo with independent defined components. @@ -140,7 +140,7 @@ job4: #### Scheduled run -GitLab CI/CD has an easy to use UI to [schedule pipelines](../pipelines/schedules.md). Also, [rules](../yaml/README.md#rules) can be used to determine if jobs should be included or excluded from a scheduled pipeline. +GitLab CI/CD has an easy to use UI to [schedule pipelines](../pipelines/schedules.md). Also, [rules](../yaml/index.md#rules) can be used to determine if jobs should be included or excluded from a scheduled pipeline. CircleCI example of a scheduled workflow: @@ -159,7 +159,7 @@ scheduled-workflow: - build ``` -Example of the same scheduled pipeline using [`rules`](../yaml/README.md#rules) in GitLab CI/CD: +Example of the same scheduled pipeline using [`rules`](../yaml/index.md#rules) in GitLab CI/CD: ```yaml job1: @@ -188,7 +188,7 @@ release-branch-workflow: - testing ``` -Example of the same workflow using [`when: manual`](../yaml/README.md#whenmanual) in GitLab CI/CD: +Example of the same workflow using [`when: manual`](../yaml/index.md#whenmanual) in GitLab CI/CD: ```yaml deploy_prod: @@ -200,7 +200,7 @@ deploy_prod: ### Filter job by branch -[Rules](../yaml/README.md#rules) are a mechanism to determine if the job runs for a specific branch. +[Rules](../yaml/index.md#rules) are a mechanism to determine if the job runs for a specific branch. CircleCI example of a job filtered by branch: @@ -294,7 +294,7 @@ GitLab.com shared runners: ### Machine and specific build environments -[Tags](../yaml/README.md#tags) can be used to run jobs on different platforms, by telling GitLab which runners should run the jobs. +[Tags](../yaml/index.md#tags) can be used to run jobs on different platforms, by telling GitLab which runners should run the jobs. CircleCI example of a job running on a specific environment: diff --git a/doc/ci/migration/jenkins.md b/doc/ci/migration/jenkins.md index 236101af0fd..9f2115fa4a0 100644 --- a/doc/ci/migration/jenkins.md +++ b/doc/ci/migration/jenkins.md @@ -19,7 +19,7 @@ that were able to quickly complete this migration: 1. Learn the importance of [managing the organizational transition](#managing-the-organizational-transition). 1. [Add runners](../runners/index.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/index.md) and [Pipeline Configuration Reference](../yaml/README.md). + 1. Review the [Quick Start Guide](../quick_start/index.md) and [Pipeline Configuration Reference](../yaml/index.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). @@ -71,7 +71,7 @@ If you are interested in helping GitLab test the wrapper, join our [public testi There are some high level differences between the products worth mentioning: - With GitLab you don't need a root `pipeline` keyword to wrap everything. -- The way pipelines are triggered and [trigger other pipelines](../yaml/README.md#trigger) +- The way pipelines are triggered and [trigger other pipelines](../yaml/index.md#trigger) is different than Jenkins. GitLab pipelines can be triggered: - on push @@ -82,34 +82,34 @@ There are some high level differences between the products worth mentioning: - 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). + with the [`rules` syntax](../yaml/index.md#rules). - GitLab [pipeline scheduling concepts](../pipelines/schedules.md) are also different from Jenkins. -- You can reuse pipeline configurations using the [`include` keyword](../yaml/README.md#include) +- You can reuse pipeline configurations using the [`include` keyword](../yaml/index.md#include) and [templates](#templates). Your templates can be kept in a central repository (with different permissions), and then any project can use them. This central project could also contain scripts or other reusable code. -- You can also use the [`extends` keyword](../yaml/README.md#extends) to reuse configuration +- You can also use the [`extends` keyword](../yaml/index.md#extends) to reuse configuration within a single pipeline configuration. - All jobs within a single stage always run in parallel, and all stages run in sequence. We are planning to allow certain jobs to break this sequencing as needed with our [directed acyclic graph](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/47063) feature. -- The [`parallel`](../yaml/README.md#parallel) keyword can automatically parallelize tasks, +- The [`parallel`](../yaml/index.md#parallel) keyword can automatically parallelize tasks, like tests that support parallelization. - Normally all jobs within a single stage run in parallel, and all stages run in sequence. There are different [pipeline architectures](../pipelines/pipeline_architectures.md) that allow you to change this behavior. -- The new [`rules` syntax](../yaml/README.md#rules) is the recommended method of +- The new [`rules` syntax](../yaml/index.md#rules) is the recommended method of controlling when different jobs run. It is more powerful than the `only/except` syntax. - One important difference is that jobs run independently of each other and have a fresh environment in each job. Passing artifacts between jobs is controlled using the - [`artifacts`](../yaml/README.md#artifacts) and [`dependencies`](../yaml/README.md#dependencies) + [`artifacts`](../yaml/index.md#artifacts) and [`dependencies`](../yaml/index.md#dependencies) keywords. When finished, use the planned [Workspaces](https://gitlab.com/gitlab-org/gitlab/-/issues/29265) feature to more easily persist a common workspace between serial jobs. - The `.gitlab-ci.yml` file is checked in to the root of your repository, much like a Jenkinsfile, but - is in the YAML format (see [complete reference](../yaml/README.md)) instead of a Groovy DSL. It's most + is in the YAML format (see [complete reference](../yaml/index.md)) instead of a Groovy DSL. It's most analogous to the declarative Jenkinsfile format. -- Manual approvals or gates can be set up as [`when:manual` jobs](../yaml/README.md#whenmanual). These can - also leverage [`protected environments`](../yaml/README.md#protecting-manual-jobs) +- Manual approvals or gates can be set up as [`when:manual` jobs](../yaml/index.md#whenmanual). These can + also leverage [`protected environments`](../yaml/index.md#protecting-manual-jobs) to control who is able to approve them. - GitLab comes with a [container registry](../../user/packages/container_registry/index.md), and we recommend using container images to set up your build environment. For example, set up one pipeline that builds your build environment @@ -154,8 +154,8 @@ and manage. That said, we do of course still value DRY (don't repeat yourself) principles and want to ensure that behaviors of your jobs can be codified once and applied as needed. You can use the `extends:` syntax to -[reuse configuration in your jobs](../yaml/README.md#extends), and `include:` can -be used to [reuse pipeline configurations](../yaml/README.md#include) in pipelines +[reuse configuration in your jobs](../yaml/index.md#extends), and `include:` can +be used to [reuse pipeline configurations](../yaml/index.md#include) in pipelines in different projects: ```yaml @@ -234,7 +234,7 @@ We also support using [tags](../runners/configure_runners.md#use-tags-to-limit-t to different runners (execution agents). The `agent` section also allows you to define which Docker images should be used for execution, for which we use -the [`image`](../yaml/README.md#image) keyword. The `image` can be set on a single job or at the top level, in which +the [`image`](../yaml/index.md#image) keyword. The `image` can be set on a single job or at the top level, in which case it applies to all jobs in the pipeline: ```yaml @@ -258,7 +258,7 @@ stages: ``` Setting a step to be performed before and after any job can be done via the -[`before_script`](../yaml/README.md#before_script) and [`after_script`](../yaml/README.md#after_script) keywords: +[`before_script`](../yaml/index.md#before_script) and [`after_script`](../yaml/index.md#after_script) keywords: ```yaml default: @@ -268,10 +268,10 @@ default: #### `stages` -GitLab CI/CD also lets you define stages, but is a little bit more free-form to configure. The GitLab [`stages` keyword](../yaml/README.md#stages) +GitLab CI/CD also lets you define stages, but is a little bit more free-form to configure. The GitLab [`stages` keyword](../yaml/index.md#stages) is a top level setting that enumerates the list of stages, but you are not required to nest individual jobs underneath the `stages` section. Any job defined in the `.gitlab-ci.yml` can be made a part of any stage through use of the -[`stage:` keyword](../yaml/README.md#stage). +[`stage:` keyword](../yaml/index.md#stage). Note that, unless otherwise specified, every pipeline is instantiated with a `build`, `test`, and `deploy` stage which are run in that order. Jobs that have no `stage` defined are placed by default in the `test` stage. @@ -289,7 +289,7 @@ my_job: #### `steps` -The `steps` section is equivalent to the [`script` section](../yaml/README.md#script) of an individual job. This is +The `steps` section is equivalent to the [`script` section](../yaml/index.md#script) of an individual job. This is a simple YAML array with each line representing an individual command to be run: ```yaml @@ -303,7 +303,7 @@ my_job: #### `environment` -In GitLab, we use the [`variables` keyword](../yaml/README.md#variables) to define different variables at runtime. +In GitLab, we use the [`variables` keyword](../yaml/index.md#variables) to define different variables at runtime. These can also be set up through the GitLab UI, under CI/CD settings. See also our [general documentation on variables](../variables/index.md), including the section on [protected variables](../variables/index.md#protect-a-cicd-variable) which can be used to limit access to certain variables to certain environments or runners: @@ -318,7 +318,7 @@ variables: Here, options for different things exist associated with the object in question itself. For example, options related to jobs are defined in relation to the job itself. If you're looking for a certain option, you should be able to find -where it's located by searching our [complete configuration reference](../yaml/README.md) page. +where it's located by searching our [complete configuration reference](../yaml/index.md) page. #### `parameters` @@ -347,9 +347,9 @@ variable entry. #### `when` -GitLab does support a [`when` keyword](../yaml/README.md#when) which is used to indicate when a job should be +GitLab does support a [`when` keyword](../yaml/index.md#when) which is used to indicate when a job should be run in case of (or despite) failure, but most of the logic for controlling pipelines can be found in -our very powerful [`rules` system](../yaml/README.md#rules): +our very powerful [`rules` system](../yaml/index.md#rules): ```yaml my_job: diff --git a/doc/ci/multi_project_pipelines.md b/doc/ci/multi_project_pipelines.md index 77d8c58ce95..ba3bb4d870c 100644 --- a/doc/ci/multi_project_pipelines.md +++ b/doc/ci/multi_project_pipelines.md @@ -78,17 +78,17 @@ the `staging` job is marked as _failed_. #### Trigger job configuration keywords -Trigger jobs can use only a limited set of the GitLab CI/CD [configuration keywords](yaml/README.md). +Trigger jobs can use only a limited set of the GitLab CI/CD [configuration keywords](yaml/index.md). The keywords available for use in trigger jobs are: -- [`trigger`](yaml/README.md#trigger) -- [`stage`](yaml/README.md#stage) -- [`allow_failure`](yaml/README.md#allow_failure) -- [`rules`](yaml/README.md#rules) -- [`only` and `except`](yaml/README.md#only--except) -- [`when`](yaml/README.md#when) (only with a value of `on_success`, `on_failure`, or `always`) -- [`extends`](yaml/README.md#extends) -- [`needs`](yaml/README.md#needs) +- [`trigger`](yaml/index.md#trigger) +- [`stage`](yaml/index.md#stage) +- [`allow_failure`](yaml/index.md#allow_failure) +- [`rules`](yaml/index.md#rules) +- [`only` and `except`](yaml/index.md#only--except) +- [`when`](yaml/index.md#when) (only with a value of `on_success`, `on_failure`, or `always`) +- [`extends`](yaml/index.md#extends) +- [`needs`](yaml/index.md#needs) #### Specify a downstream pipeline branch @@ -175,7 +175,7 @@ the ones defined in the upstream project take precedence. #### Pass CI/CD variables to a downstream pipeline by using variable inheritance -You can pass variables to a downstream pipeline with [`dotenv` variable inheritance](variables/index.md#pass-an-environment-variable-to-another-job) and [cross project artifact downloads](yaml/README.md#cross-project-artifact-downloads-with-needs). +You can pass variables to a downstream pipeline with [`dotenv` variable inheritance](variables/index.md#pass-an-environment-variable-to-another-job) and [cross project artifact downloads](yaml/index.md#cross-project-artifact-downloads-with-needs). In the upstream pipeline: @@ -215,14 +215,14 @@ In the upstream pipeline: #### Use `rules` or `only`/`except` with multi-project pipelines -You can use CI/CD variables or the [`rules`](yaml/README.md#rulesif) keyword to +You can use CI/CD variables or the [`rules`](yaml/index.md#rulesif) keyword to [control job behavior](jobs/job_control.md) for multi-project pipelines. When a -downstream pipeline is triggered with the [`trigger`](yaml/README.md#trigger) keyword, +downstream pipeline is triggered with the [`trigger`](yaml/index.md#trigger) keyword, the value of the [`$CI_PIPELINE_SOURCE` predefined variable](variables/predefined_variables.md) is `pipeline` for all its jobs. -If you use [`only/except`](yaml/README.md#only--except) to control job behavior, use the -[`pipelines`](yaml/README.md#onlyrefs--exceptrefs) keyword. +If you use [`only/except`](yaml/index.md#only--except) to control job behavior, use the +[`pipelines`](yaml/index.md#onlyrefs--exceptrefs) keyword. #### Mirror status of a triggered pipeline in the trigger job @@ -267,10 +267,10 @@ outbound connections for upstream and downstream pipeline dependencies. When using: -- CI/CD variables or [`rules`](yaml/README.md#rulesif) to control job behavior, the value of +- CI/CD variables or [`rules`](yaml/index.md#rulesif) to control job behavior, the value of the [`$CI_PIPELINE_SOURCE` predefined variable](variables/predefined_variables.md) is `pipeline` for multi-project pipeline triggered through the API with `CI_JOB_TOKEN`. -- [`only/except`](yaml/README.md#only--except) to control job behavior, use the +- [`only/except`](yaml/index.md#only--except) to control job behavior, use the `pipelines` keyword. ## Trigger a pipeline when an upstream project is rebuilt **(PREMIUM)** diff --git a/doc/ci/parent_child_pipelines.md b/doc/ci/parent_child_pipelines.md index d00d94dabb3..05adcd42898 100644 --- a/doc/ci/parent_child_pipelines.md +++ b/doc/ci/parent_child_pipelines.md @@ -15,7 +15,7 @@ As pipelines grow more complex, a few related problems start to emerge: job in next stage begins, causes arbitrary waits, slowing things down. - Configuration for the single global pipeline becomes very long and complicated, making it hard to manage. -- Imports with [`include`](yaml/README.md#include) increase the complexity of the configuration, and create the potential +- Imports with [`include`](yaml/index.md#include) increase the complexity of the configuration, and create the potential for namespace collisions where jobs are unintentionally duplicated. - Pipeline UX can become unwieldy with so many jobs and stages to work with. @@ -38,12 +38,12 @@ set of concurrently running child pipelines, but within the same project: Child pipelines work well with other GitLab CI/CD features: -- Use [`rules: changes`](yaml/README.md#ruleschanges) to trigger pipelines only when +- Use [`rules: changes`](yaml/index.md#ruleschanges) to trigger pipelines only when certain files change. This is useful for monorepos, for example. - Since the parent pipeline in `.gitlab-ci.yml` and the child pipeline run as normal pipelines, they can have their own behaviors and sequencing in relation to triggers. -See the [`trigger:`](yaml/README.md#trigger) keyword documentation for full details on how to +See the [`trigger:`](yaml/index.md#trigger) keyword documentation for full details on how to include the child pipeline configuration. @@ -51,7 +51,7 @@ For an overview, see [Parent-Child Pipelines feature demo](https://youtu.be/n8Kp ## Examples -The simplest case is [triggering a child pipeline](yaml/README.md#trigger) using a +The simplest case is [triggering a child pipeline](yaml/index.md#trigger) using a local YAML file to define the pipeline configuration. In this case, the parent pipeline triggers the child pipeline, and continues without waiting: @@ -72,7 +72,7 @@ microservice_a: ``` In [GitLab 13.5](https://gitlab.com/gitlab-org/gitlab/-/issues/205157) and later, -you can use [`include:file`](yaml/README.md#includefile) to trigger child pipelines +you can use [`include:file`](yaml/index.md#includefile) to trigger child pipelines with a configuration file in a different project: ```yaml @@ -148,7 +148,7 @@ microservice_a: > [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/35632) in GitLab 12.9. Instead of running a child pipeline from a static YAML file, you can define a job that runs -your own script to generate a YAML file, which is then [used to trigger a child pipeline](yaml/README.md#trigger-child-pipeline-with-generated-configuration-file). +your own script to generate a YAML file, which is then [used to trigger a child pipeline](yaml/index.md#trigger-child-pipeline-with-generated-configuration-file). This technique can be very powerful in generating pipelines targeting content that changed or to build a matrix of targets and architectures. diff --git a/doc/ci/pipeline_editor/index.md b/doc/ci/pipeline_editor/index.md index 1527a05d3d7..6e0ba8fa33f 100644 --- a/doc/ci/pipeline_editor/index.md +++ b/doc/ci/pipeline_editor/index.md @@ -18,7 +18,7 @@ From the pipeline editor page you can: - Select the branch to work from. [Introduced in GitLab 13.12](https://gitlab.com/gitlab-org/gitlab/-/issues/326189), disabled by default. - [Validate](#validate-ci-configuration) your configuration syntax while editing the file. - Do a deeper [lint](#lint-ci-configuration) of your configuration, that verifies it with any configuration - added with the [`include`](../yaml/README.md#include) keyword. + added with the [`include`](../yaml/index.md#include) keyword. - See a [visualization](#visualize-ci-configuration) of the current configuration. - View an [expanded](#view-expanded-configuration) version of your configuration. - [Commit](#commit-changes-to-ci-configuration) the changes to a specific branch. @@ -58,7 +58,7 @@ reflected in the CI lint. It displays the same results as the existing [CI Lint To view a visualization of your `gitlab-ci.yml` configuration, in your project, go to **CI/CD > Editor**, and then select the **Visualize** tab. The -visualization shows all stages and jobs. Any [`needs`](../yaml/README.md#needs) +visualization shows all stages and jobs. Any [`needs`](../yaml/index.md#needs) relationships are displayed as lines connecting jobs together, showing the hierarchy of execution: @@ -80,10 +80,10 @@ To view the fully expanded CI/CD configuration as one combined file, go to the pipeline editor's **View merged YAML** tab. This tab displays an expanded configuration where: -- Configuration imported with [`include`](../yaml/README.md#include) is copied into the view. -- Jobs that use [`extends`](../yaml/README.md#extends) display with the - [extended configuration merged into the job](../yaml/README.md#merge-details). -- YAML anchors are [replaced with the linked configuration](../yaml/README.md#anchors). +- Configuration imported with [`include`](../yaml/index.md#include) is copied into the view. +- Jobs that use [`extends`](../yaml/index.md#extends) display with the + [extended configuration merged into the job](../yaml/index.md#merge-details). +- YAML anchors are [replaced with the linked configuration](../yaml/index.md#anchors). ## Commit changes to CI configuration diff --git a/doc/ci/pipelines/index.md b/doc/ci/pipelines/index.md index e8dda75cf21..5041b56bba7 100644 --- a/doc/ci/pipelines/index.md +++ b/doc/ci/pipelines/index.md @@ -67,9 +67,9 @@ Pipelines can be configured in many different ways: Pipelines and their component jobs and stages are defined in the CI/CD pipeline configuration file for each project. - [Jobs](../jobs/index.md) are the basic configuration component. -- Stages are defined by using the [`stages`](../yaml/README.md#stages) keyword. +- Stages are defined by using the [`stages`](../yaml/index.md#stages) keyword. -For a list of configuration options in the CI pipeline file, see the [GitLab CI/CD Pipeline Configuration Reference](../yaml/README.md). +For a list of configuration options in the CI pipeline file, see the [GitLab CI/CD Pipeline Configuration Reference](../yaml/index.md). You can also configure specific aspects of your pipelines through the GitLab UI. For example: @@ -146,7 +146,7 @@ The pipeline now executes the jobs as configured. > [Introduced in](https://gitlab.com/gitlab-org/gitlab/-/issues/30101) GitLab 13.7. -You can use the [`value` and `description`](../yaml/README.md#prefill-variables-in-manual-pipelines) +You can use the [`value` and `description`](../yaml/index.md#prefill-variables-in-manual-pipelines) keywords to define [pipeline-level (global) variables](../variables/index.md#create-a-custom-cicd-variable-in-the-gitlab-ciyml-file) that are prefilled when running a pipeline manually. @@ -200,7 +200,7 @@ For each `var` or `file_var`, a key and value are required. ### Add manual interaction to your pipeline -Manual actions, configured using the [`when:manual`](../yaml/README.md#whenmanual) keyword, +Manual actions, configured using the [`when:manual`](../yaml/index.md#whenmanual) keyword, allow you to require manual interaction before moving forward in the pipeline. You can do this straight from the pipeline graph. Just click the play button @@ -347,7 +347,7 @@ You can group the jobs by: ![jobs grouped by stage](img/pipelines_graph_stage_view_v13_12.png) - [Job dependencies](#view-job-dependencies-in-the-pipeline-graph), which arranges - jobs based on their [`needs`](../yaml/README.md#needs) dependencies. + jobs based on their [`needs`](../yaml/index.md#needs) dependencies. [Multi-project pipeline graphs](../multi_project_pipelines.md#multi-project-pipeline-visualization) help you visualize the entire pipeline, including all cross-project inter-dependencies. **(PREMIUM)** @@ -365,7 +365,7 @@ This in-development feature might not be available for your use. There can be [risks when enabling features still in development](../../user/feature_flags.md#risks-when-enabling-features-still-in-development). Refer to this feature's version history for more details. -You can arrange jobs in the pipeline graph based on their [`needs`](../yaml/README.md#needs) +You can arrange jobs in the pipeline graph based on their [`needs`](../yaml/index.md#needs) dependencies. Jobs in the leftmost column run first, and jobs that depend on them are grouped in the next columns. diff --git a/doc/ci/pipelines/job_artifacts.md b/doc/ci/pipelines/job_artifacts.md index 0c4f52142ac..eed30648b75 100644 --- a/doc/ci/pipelines/job_artifacts.md +++ b/doc/ci/pipelines/job_artifacts.md @@ -48,7 +48,7 @@ is used. If you run two types of pipelines (like branch and scheduled) for the same ref, the pipeline that finishes later creates the job artifact. -For more examples, view the [keyword reference for the `.gitlab-ci.yml` file](../yaml/README.md#artifacts). +For more examples, view the [keyword reference for the `.gitlab-ci.yml` file](../yaml/index.md#artifacts). ## Download job artifacts @@ -173,7 +173,7 @@ https://gitlab.com/gitlab-org/gitlab/-/jobs/artifacts/main/file/htmlcov/index.ht ## When job artifacts are deleted -See the [`expire_in`](../yaml/README.md#artifactsexpire_in) documentation for information on when +See the [`expire_in`](../yaml/index.md#artifactsexpire_in) documentation for information on when job artifacts are deleted. ### Keep artifacts from most recent successful jobs diff --git a/doc/ci/pipelines/pipeline_architectures.md b/doc/ci/pipelines/pipeline_architectures.md index 78031ec1d97..184bc5a956a 100644 --- a/doc/ci/pipelines/pipeline_architectures.md +++ b/doc/ci/pipelines/pipeline_architectures.md @@ -18,7 +18,7 @@ own advantages. These methods can be mixed and matched if needed: - [Child/Parent Pipelines](#child--parent-pipelines): Good for monorepos and projects with lots of independently defined components. For more details about -any of the keywords used below, check out our [CI YAML reference](../yaml/README.md) for details. +any of the keywords used below, check out our [CI YAML reference](../yaml/index.md) for details. ## Basic Pipelines @@ -96,7 +96,7 @@ deploy_b: If efficiency is important to you and you want everything to run as quickly as possible, you can use [Directed Acyclic Graphs (DAG)](../directed_acyclic_graph/index.md). Use the -[`needs` keyword](../yaml/README.md#needs) to define dependency relationships between +[`needs` keyword](../yaml/index.md#needs) to define dependency relationships between your jobs. When GitLab knows the relationships between your jobs, it can run everything as fast as possible, and even skips into subsequent stages when possible. @@ -163,12 +163,12 @@ deploy_b: In the examples above, it's clear we've got two types of things that could be built independently. This is an ideal case for using [Child / Parent Pipelines](../parent_child_pipelines.md)) via -the [`trigger` keyword](../yaml/README.md#trigger). It separates out the configuration +the [`trigger` keyword](../yaml/index.md#trigger). It separates out the configuration into multiple files, keeping things very simple. You can also combine this with: -- The [`rules` keyword](../yaml/README.md#rules): For example, have the child pipelines triggered only +- The [`rules` keyword](../yaml/index.md#rules): For example, have the child pipelines triggered only when there are changes to that area. -- The [`include` keyword](../yaml/README.md#include): Bring in common behaviors, ensuring +- The [`include` keyword](../yaml/index.md#include): Bring in common behaviors, ensuring you are not repeating yourself. - [DAG pipelines](#directed-acyclic-graph-pipelines) inside of child pipelines, achieving the benefits of both. diff --git a/doc/ci/pipelines/pipeline_artifacts.md b/doc/ci/pipelines/pipeline_artifacts.md index b80a056bbca..55555571f97 100644 --- a/doc/ci/pipelines/pipeline_artifacts.md +++ b/doc/ci/pipelines/pipeline_artifacts.md @@ -9,7 +9,7 @@ type: reference, howto Pipeline artifacts are files created by GitLab after a pipeline finishes. These are different than [job artifacts](job_artifacts.md) because they are not explicitly managed by the `.gitlab-ci.yml` definitions. -Pipeline artifacts are used by the [test coverage visualization feature](../../user/project/merge_requests/test_coverage_visualization.md) to collect coverage information. It uses the [`artifacts: reports`](../yaml/README.md#artifactsreports) CI/CD keyword. +Pipeline artifacts are used by the [test coverage visualization feature](../../user/project/merge_requests/test_coverage_visualization.md) to collect coverage information. It uses the [`artifacts: reports`](../yaml/index.md#artifactsreports) CI/CD keyword. ## Storage diff --git a/doc/ci/pipelines/pipeline_efficiency.md b/doc/ci/pipelines/pipeline_efficiency.md index 155b83f9d33..5d8d4fa8ff1 100644 --- a/doc/ci/pipelines/pipeline_efficiency.md +++ b/doc/ci/pipelines/pipeline_efficiency.md @@ -146,7 +146,7 @@ with embedded metric charts and all valuable details to analyze the problem. Review the storage use of the following to help analyze costs and efficiency: -- [Job artifacts](job_artifacts.md) and their [`expire_in`](../yaml/README.md#artifactsexpire_in) +- [Job artifacts](job_artifacts.md) and their [`expire_in`](../yaml/index.md#artifactsexpire_in) configuration. If kept for too long, storage usage grows and could slow pipelines down. - [Container registry](../../user/packages/container_registry/index.md) usage. - [Package registry](../../user/packages/package_registry/index.md) usage. @@ -162,9 +162,9 @@ make pipelines run faster and more efficiently. Try to find which jobs don't need to run in all situations, and use pipeline configuration to stop them from running: -- Use the [`interruptible`](../yaml/README.md#interruptible) keyword to stop old pipelines +- Use the [`interruptible`](../yaml/index.md#interruptible) keyword to stop old pipelines when they are superseded by a newer pipeline. -- Use [`rules`](../yaml/README.md#rules) to skip tests that aren't needed. For example, +- Use [`rules`](../yaml/index.md#rules) to skip tests that aren't needed. For example, skip backend tests when only the frontend code is changed. - Run non-essential [scheduled pipelines](schedules.md) less frequently. @@ -195,7 +195,7 @@ Another optimization method is to [cache](../caching/index.md) dependencies. If dependencies change rarely, like [NodeJS `/node_modules`](../caching/index.md#cache-nodejs-dependencies), caching can make pipeline execution much faster. -You can use [`cache:when`](../yaml/README.md#cachewhen) to cache downloaded dependencies +You can use [`cache:when`](../yaml/index.md#cachewhen) to cache downloaded dependencies even when a job fails. ### Docker Images diff --git a/doc/ci/pipelines/schedules.md b/doc/ci/pipelines/schedules.md index c6a40039816..9cb600ae551 100644 --- a/doc/ci/pipelines/schedules.md +++ b/doc/ci/pipelines/schedules.md @@ -52,14 +52,14 @@ is installed on. ### Using variables You can pass any number of arbitrary variables. They are available in -GitLab CI/CD so that they can be used in your [`.gitlab-ci.yml` file](../../ci/yaml/README.md). +GitLab CI/CD so that they can be used in your [`.gitlab-ci.yml` file](../../ci/yaml/index.md). ![Scheduled pipeline variables](img/pipeline_schedule_variables.png) ### Using `rules` To configure a job to be executed only when the pipeline has been -scheduled, use the [`rules`](../yaml/README.md#rules) keyword. +scheduled, use the [`rules`](../yaml/index.md#rules) keyword. In this example, `make world` runs in scheduled pipelines, and `make build` runs in branch and tag pipelines: diff --git a/doc/ci/pipelines/settings.md b/doc/ci/pipelines/settings.md index 2e842856e55..683939ac81a 100644 --- a/doc/ci/pipelines/settings.md +++ b/doc/ci/pipelines/settings.md @@ -228,7 +228,7 @@ You can set pending or running pipelines to cancel automatically when a new pipe 1. Check the **Auto-cancel redundant pipelines** checkbox. 1. Click **Save changes**. -Use the [`interruptible`](../yaml/README.md#interruptible) keyword to indicate if a +Use the [`interruptible`](../yaml/index.md#interruptible) keyword to indicate if a running job can be cancelled before it completes. ## Skip outdated deployment jobs diff --git a/doc/ci/quick_start/index.md b/doc/ci/quick_start/index.md index 225794aec17..8d800d49be3 100644 --- a/doc/ci/quick_start/index.md +++ b/doc/ci/quick_start/index.md @@ -142,7 +142,7 @@ The pipeline starts when the commit is committed. - 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). + [the `.gitlab-ci.yml` reference topic](../yaml/index.md). ### View the status of your pipeline and jobs diff --git a/doc/ci/runners/configure_runners.md b/doc/ci/runners/configure_runners.md index e143ade5b60..7f616a85c6a 100644 --- a/doc/ci/runners/configure_runners.md +++ b/doc/ci/runners/configure_runners.md @@ -169,13 +169,13 @@ GitLab CI tags are not the same as Git tags. GitLab CI tags are associated with Git tags are associated with commits. By tagging a runner for the types of jobs it can handle, you can make sure -shared runners will [only run the jobs they are equipped to run](../yaml/README.md#tags). +shared runners will [only run the jobs they are equipped to run](../yaml/index.md#tags). For instance, at GitLab we have runners tagged with `rails` if they contain the appropriate dependencies to run Rails test suites. When you [register a runner](https://docs.gitlab.com/runner/register/), its default behavior is to **only pick** -[tagged jobs](../yaml/README.md#tags). +[tagged jobs](../yaml/index.md#tags). To change this, you must have the [Owner role](../../user/permissions.md#project-members-permissions) for the project. To make a runner pick untagged jobs: @@ -250,7 +250,7 @@ You can also use variables to configure how many times a runner > - `GIT_STRATEGY=none` requires GitLab Runner v1.7+. You can set the `GIT_STRATEGY` used to fetch the repository content, either -globally or per-job in the [`variables`](../yaml/README.md#variables) section: +globally or per-job in the [`variables`](../yaml/index.md#variables) section: ```yaml variables: @@ -281,7 +281,7 @@ The `kubernetes` executor always clones into an temporary directory. A Git strategy of `none` also re-uses the local working copy, but skips all Git operations normally done by GitLab. GitLab Runner pre-clone scripts are also skipped, if present. This strategy could mean you need to add `fetch` and `checkout` commands -to [your `.gitlab-ci.yml` script](../yaml/README.md#script). +to [your `.gitlab-ci.yml` script](../yaml/index.md#script). It can be used for jobs that operate exclusively on artifacts, like a deployment job. Git repository data may be present, but it's likely out of date. You should only @@ -293,7 +293,7 @@ rely on files brought into the local working copy from cache or artifacts. The `GIT_SUBMODULE_STRATEGY` variable is used to control if / how Git submodules are included when fetching the code before a build. You can set them -globally or per-job in the [`variables`](../yaml/README.md#variables) section. +globally or per-job in the [`variables`](../yaml/index.md#variables) section. There are three possible values: `none`, `normal`, and `recursive`: @@ -332,7 +332,7 @@ For this feature to work correctly, the submodules must be configured The `GIT_CHECKOUT` variable can be used when the `GIT_STRATEGY` is set to either `clone` or `fetch` to specify whether a `git checkout` should be run. If not specified, it defaults to true. You can set them globally or per-job in the -[`variables`](../yaml/README.md#variables) section. +[`variables`](../yaml/index.md#variables) section. If set to `false`, the runner: @@ -360,7 +360,7 @@ script: The `GIT_CLEAN_FLAGS` variable is used to control the default behavior of `git clean` after checking out the sources. You can set it globally or per-job in the -[`variables`](../yaml/README.md#variables) section. +[`variables`](../yaml/index.md#variables) section. `GIT_CLEAN_FLAGS` accepts all possible options of the [`git clean`](https://git-scm.com/docs/git-clean) command. @@ -386,7 +386,7 @@ script: > [Introduced](https://gitlab.com/gitlab-org/gitlab-runner/-/issues/4142) in GitLab Runner 13.1. The `GIT_FETCH_EXTRA_FLAGS` variable is used to control the behavior of -`git fetch`. You can set it globally or per-job in the [`variables`](../yaml/README.md#variables) section. +`git fetch`. You can set it globally or per-job in the [`variables`](../yaml/index.md#variables) section. `GIT_FETCH_EXTRA_FLAGS` accepts all options of the [`git fetch`](https://git-scm.com/docs/git-fetch) command. However, `GIT_FETCH_EXTRA_FLAGS` flags are appended after the default flags that can't be modified. @@ -450,7 +450,7 @@ variables: GIT_DEPTH: "3" ``` -You can set it globally or per-job in the [`variables`](../yaml/README.md#variables) section. +You can set it globally or per-job in the [`variables`](../yaml/index.md#variables) section. ### Custom build directories @@ -559,7 +559,7 @@ variables: GET_SOURCES_ATTEMPTS: 3 ``` -You can set them globally or per-job in the [`variables`](../yaml/README.md#variables) section. +You can set them globally or per-job in the [`variables`](../yaml/index.md#variables) section. ## System calls not available on GitLab.com shared runners diff --git a/doc/ci/runners/index.md b/doc/ci/runners/index.md index de1d9cb7daa..771a0794ba8 100644 --- a/doc/ci/runners/index.md +++ b/doc/ci/runners/index.md @@ -273,12 +273,12 @@ test: for maintenance or updates. - The Windows shared runner virtual machine instances do not use the GitLab Docker executor. This means that you can't specify - [`image`](../../ci/yaml/README.md#image) or [`services`](../../ci/yaml/README.md#services) in + [`image`](../../ci/yaml/index.md#image) or [`services`](../../ci/yaml/index.md#services) in your pipeline configuration. - For the beta release, we have included a set of software packages in the base VM image. If your CI job requires additional software that's not included in this list, then you must add installation - commands to [`before_script`](../../ci/yaml/README.md#before_script) or [`script`](../../ci/yaml/README.md#script) to install the required + commands to [`before_script`](../../ci/yaml/index.md#before_script) or [`script`](../../ci/yaml/index.md#script) to install the required software. Note that each job runs on a new VM instance, so the installation of additional software packages needs to be repeated for each job in your pipeline. diff --git a/doc/ci/secrets/index.md b/doc/ci/secrets/index.md index e743f02b029..6145a953571 100644 --- a/doc/ci/secrets/index.md +++ b/doc/ci/secrets/index.md @@ -14,7 +14,7 @@ sensitive information can be items like API tokens, database credentials, or pri Secrets are sourced from your secrets provider. Unlike CI/CD variables, which are always presented to a job, secrets must be explicitly -required by a job. Read [GitLab CI/CD pipeline configuration reference](../yaml/README.md#secrets) +required by a job. Read [GitLab CI/CD pipeline configuration reference](../yaml/index.md#secrets) for more information about the syntax. GitLab has selected [Vault by HashiCorp](https://www.vaultproject.io) as the @@ -117,7 +117,7 @@ The path to this file is stored in a CI/CD variable named `DATABASE_PASSWORD`, similar to [variables of type `file`](../variables/index.md#cicd-variable-types). For more information about the supported syntax, read the -[`.gitlab-ci.yml` reference](../yaml/README.md#secretsvault). +[`.gitlab-ci.yml` reference](../yaml/index.md#secretsvault). ## Configure Vault server roles diff --git a/doc/ci/ssh_keys/index.md b/doc/ci/ssh_keys/index.md index 390d5984a45..a27f6ac4983 100644 --- a/doc/ci/ssh_keys/index.md +++ b/doc/ci/ssh_keys/index.md @@ -94,7 +94,7 @@ to access it. This is where an SSH key pair comes in handy. # - git config --global user.name "User name" ``` - The [`before_script`](../yaml/README.md#before_script) can be set globally + The [`before_script`](../yaml/index.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). diff --git a/doc/ci/triggers/index.md b/doc/ci/triggers/index.md index b3c560cea72..c2f398d1eb5 100644 --- a/doc/ci/triggers/index.md +++ b/doc/ci/triggers/index.md @@ -26,7 +26,7 @@ depending on which trigger method is used. | `pipeline` | Using the `trigger:` keyword in the CI/CD configuration file, or using the trigger API with `$CI_JOB_TOKEN`. | | `trigger` | Using the trigger API using a generated trigger token | -This also applies when using the `pipelines` or `triggers` keywords with the legacy [`only/except` basic syntax](../yaml/README.md#only--except). +This also applies when using the `pipelines` or `triggers` keywords with the legacy [`only/except` basic syntax](../yaml/index.md#only--except). ### Trigger token @@ -218,7 +218,7 @@ Using trigger variables can be proven useful for a variety of reasons: a certain variable is present. Consider the following `.gitlab-ci.yml` where we set three -[stages](../yaml/README.md#stages) and the `upload_package` job is run only +[stages](../yaml/index.md#stages) and the `upload_package` job is run only when all jobs from the test and build stages pass. When the `UPLOAD_TO_S3` variable is non-zero, `make upload` is run. diff --git a/doc/ci/troubleshooting.md b/doc/ci/troubleshooting.md index 1319f89d8b6..310118b26aa 100644 --- a/doc/ci/troubleshooting.md +++ b/doc/ci/troubleshooting.md @@ -49,7 +49,7 @@ and check if their values are what you expect. ## GitLab CI/CD documentation -The [complete `gitlab-ci.yml` reference](yaml/README.md) contains a full list of +The [complete `gitlab-ci.yml` reference](yaml/index.md) contains a full list of every keyword you may need to use to configure your pipelines. You can also look at a large number of pipeline configuration [examples](examples/index.md) @@ -105,7 +105,7 @@ If a pipeline does not seem to run at all, with no error message, it may also be due to `rules` or `only/except` configuration, or the `workflow: rules` keyword. If you are converting from `only/except` to the `rules` keyword, you should check -the [`rules` configuration details](yaml/README.md#rules) carefully. The behavior +the [`rules` configuration details](yaml/index.md#rules) carefully. The behavior of `only/except` and `rules` is different and can cause unexpected behavior when migrating between the two. @@ -123,8 +123,8 @@ This is usually caused by the `rules` configuration, and there are several ways #### A job is not in the pipeline -GitLab determines if a job is added to a pipeline based on the [`only/except`](yaml/README.md#only--except) -or [`rules`](yaml/README.md#rules) defined for the job. If it didn't run, it's probably +GitLab determines if a job is added to a pipeline based on the [`only/except`](yaml/index.md#only--except) +or [`rules`](yaml/index.md#rules) defined for the job. If it didn't run, it's probably not evaluating as you expect. #### No pipeline or the wrong type of pipeline runs @@ -141,7 +141,7 @@ be checked to make sure the jobs are added to the correct pipeline type. For example, if a merge request pipeline did not run, the jobs may have been added to a branch pipeline instead. -It's also possible that your [`workflow: rules`](yaml/README.md#workflow) configuration +It's also possible that your [`workflow: rules`](yaml/index.md#workflow) configuration blocked the pipeline, or allowed the wrong pipeline type. ### A job runs unexpectedly @@ -150,8 +150,8 @@ A common reason a job is added to a pipeline unexpectedly is because the `change keyword always evaluates to true in certain cases. For example, `changes` is always true in certain pipeline types, including scheduled pipelines and pipelines for tags. -The `changes` keyword is used in combination with [`only/except`](yaml/README.md#onlychanges--exceptchanges) -or [`rules`](yaml/README.md#ruleschanges)). It's recommended to use `changes` with +The `changes` keyword is used in combination with [`only/except`](yaml/index.md#onlychanges--exceptchanges) +or [`rules`](yaml/index.md#ruleschanges)). It's recommended to use `changes` with `rules` or `only/except` configuration that ensures the job is only added to branch pipelines or merge request pipelines. @@ -249,17 +249,17 @@ If the merge train pipeline was canceled before the merge request was merged, wi Pipeline configuration warnings are shown when you: -- [Validate configuration with the CI Lint tool](yaml/README.md). +- [Validate configuration with the CI Lint tool](yaml/index.md). - [Manually run a pipeline](pipelines/index.md#run-a-pipeline-manually). ### "Job may allow multiple pipelines to run for a single action" warning -When you use [`rules`](yaml/README.md#rules) with a `when:` clause without an `if:` +When you use [`rules`](yaml/index.md#rules) with a `when:` clause without an `if:` clause, multiple pipelines may run. Usually this occurs when you push a commit to a branch that has an open merge request associated with it. To [prevent duplicate pipelines](jobs/job_control.md#avoid-duplicate-pipelines), use -[`workflow: rules`](yaml/README.md#workflow) or rewrite your rules to control +[`workflow: rules`](yaml/index.md#workflow) or rewrite your rules to control which pipelines can run. ### Console workaround if job using resource_group gets stuck diff --git a/doc/ci/unit_test_reports.md b/doc/ci/unit_test_reports.md index 7b5f6b5167d..731e658c739 100644 --- a/doc/ci/unit_test_reports.md +++ b/doc/ci/unit_test_reports.md @@ -41,7 +41,7 @@ Consider the following workflow: ## How it works First, GitLab Runner uploads all [JUnit report format XML files](https://www.ibm.com/support/knowledgecenter/en/SSQ2R2_14.1.0/com.ibm.rsar.analysis.codereview.cobol.doc/topics/cac_useresults_junit.html) -as [artifacts](yaml/README.md#artifactsreportsjunit) to GitLab. Then, when you visit a merge request, GitLab starts +as [artifacts](yaml/index.md#artifactsreportsjunit) to GitLab. Then, when you visit a merge request, GitLab starts comparing the head and base branch's JUnit report format XML files, where: - The base branch is the target branch (usually the default branch). @@ -77,7 +77,7 @@ If a test failed in the project's default branch in the last 14 days, a message ## How to set it up To enable the Unit test reports in merge requests, you need to add -[`artifacts:reports:junit`](yaml/README.md#artifactsreportsjunit) +[`artifacts:reports:junit`](yaml/index.md#artifactsreportsjunit) in `.gitlab-ci.yml`, and specify the path(s) of the generated test reports. The reports must be `.xml` files, otherwise [GitLab returns an Error 500](https://gitlab.com/gitlab-org/gitlab/-/issues/216575). @@ -87,8 +87,8 @@ XML reports are stored in GitLab as artifacts and their results are shown in the merge request widget. To make the Unit test report output files browsable, include them with the -[`artifacts:paths`](yaml/README.md#artifactspaths) keyword as well, as shown in the [Ruby example](#ruby-example). -To upload the report even if the job fails (for example if the tests do not pass), use the [`artifacts:when:always`](yaml/README.md#artifactswhen) +[`artifacts:paths`](yaml/index.md#artifactspaths) keyword as well, as shown in the [Ruby example](#ruby-example). +To upload the report even if the job fails (for example if the tests do not pass), use the [`artifacts:when:always`](yaml/index.md#artifactswhen) keyword. You cannot have multiple tests with the same name and class in your JUnit report format XML file. @@ -355,7 +355,7 @@ If parsing JUnit report XML results in an error, an indicator is shown next to t > - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/202114) in GitLab 13.0 behind the `:junit_pipeline_screenshots_view` feature flag, disabled by default. > - The feature flag was removed and was [made generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/216979) in GitLab 13.12. -Upload your screenshots as [artifacts](yaml/README.md#artifactsreportsjunit) to GitLab. If JUnit +Upload your screenshots as [artifacts](yaml/index.md#artifactsreportsjunit) to GitLab. If JUnit report format XML files contain an `attachment` tag, GitLab parses the attachment. Note that: - The `attachment` tag **must** contain the relative path to `$CI_PROJECT_DIR` of the screenshots you uploaded. For @@ -368,7 +368,7 @@ report format XML files contain an `attachment` tag, GitLab parses the attachmen ``` - You should set the job that uploads the screenshot to - [`artifacts:when: always`](yaml/README.md#artifactswhen) so that it still uploads a screenshot + [`artifacts:when: always`](yaml/index.md#artifactswhen) so that it still uploads a screenshot when a test fails. A link to the test case attachment appears in the test case details in diff --git a/doc/ci/variables/index.md b/doc/ci/variables/index.md index 68980e19399..d7c9e3e164d 100644 --- a/doc/ci/variables/index.md +++ b/doc/ci/variables/index.md @@ -73,7 +73,7 @@ Make sure each variable is defined for the [scope you want to use it in](where_v ### Create a custom CI/CD variable in the `.gitlab-ci.yml` file -To create a custom variable in the [`.gitlab-ci.yml`](../yaml/README.md#variables) file, +To create a custom variable in the [`.gitlab-ci.yml`](../yaml/index.md#variables) file, define the variable and value with `variables` keyword. You can use the `variables` keyword in a job or at the top level of the `.gitlab-ci.yml` file. @@ -119,7 +119,7 @@ script: - 'eval "$LS_CMD"' # Executes 'ls -al $TMP_DIR' ``` -Use the [`value` and `description`](../yaml/README.md#prefill-variables-in-manual-pipelines) +Use the [`value` and `description`](../yaml/index.md#prefill-variables-in-manual-pipelines) keywords to define [variables that are prefilled](../pipelines/index.md#prefill-variables-in-manual-pipelines) for [manually-triggered pipelines](../pipelines/index.md#run-a-pipeline-manually). @@ -493,13 +493,13 @@ These variables cannot be used as CI/CD variables to configure a pipeline, but they can be used in job scripts. 1. In the job script, save the variable as a `.env` file. -1. Save the `.env` file as an [`artifacts:reports:dotenv`](../yaml/README.md#artifactsreportsdotenv) +1. Save the `.env` file as an [`artifacts:reports:dotenv`](../yaml/index.md#artifactsreportsdotenv) artifact. -1. Set a job in a later stage to receive the artifact by using the [`dependencies`](../yaml/README.md#dependencies) - or the [`needs`](../yaml/README.md#artifact-downloads-with-needs) keywords. +1. Set a job in a later stage to receive the artifact by using the [`dependencies`](../yaml/index.md#dependencies) + or the [`needs`](../yaml/index.md#artifact-downloads-with-needs) keywords. 1. The later job can then [use the variable in scripts](#use-cicd-variables-in-job-scripts). -For example, with the [`dependencies`](../yaml/README.md#dependencies) keyword: +For example, with the [`dependencies`](../yaml/index.md#dependencies) keyword: ```yaml build: @@ -518,7 +518,7 @@ deploy: - build ``` -For example, with the [`needs`](../yaml/README.md#artifact-downloads-with-needs) keyword: +For example, with the [`needs`](../yaml/index.md#artifact-downloads-with-needs) keyword: ```yaml build: diff --git a/doc/ci/variables/predefined_variables.md b/doc/ci/variables/predefined_variables.md index d8b385db9ef..0180da79c2c 100644 --- a/doc/ci/variables/predefined_variables.md +++ b/doc/ci/variables/predefined_variables.md @@ -49,10 +49,10 @@ There are also [Kubernetes-specific deployment variables](../../user/project/clu | `CI_DEPLOY_PASSWORD` | 10.8 | all | The authentication password of the [GitLab Deploy Token](../../user/project/deploy_tokens/index.md#gitlab-deploy-token), if the project has one. | | `CI_DEPLOY_USER` | 10.8 | all | The authentication username of the [GitLab Deploy Token](../../user/project/deploy_tokens/index.md#gitlab-deploy-token), if the project has one. | | `CI_DISPOSABLE_ENVIRONMENT` | all | 10.1 | Only available if the job is executed in a disposable environment (something that is created only for this job and disposed of/destroyed after the execution - all executors except `shell` and `ssh`). `true` when available. | -| `CI_ENVIRONMENT_NAME` | 8.15 | all | The name of the environment for this job. Available if [`environment:name`](../yaml/README.md#environmentname) is set. | -| `CI_ENVIRONMENT_SLUG` | 8.15 | all | The simplified version of the environment name, suitable for inclusion in DNS, URLs, Kubernetes labels, and so on. Available if [`environment:name`](../yaml/README.md#environmentname) is set. The slug is [truncated to 24 characters](https://gitlab.com/gitlab-org/gitlab/-/issues/20941). | -| `CI_ENVIRONMENT_URL` | 9.3 | all | The URL of the environment for this job. Available if [`environment:url`](../yaml/README.md#environmenturl) is set. | -| `CI_ENVIRONMENT_ACTION` | 13.11 | all | The action annotation specified for this job's environment. Available if [`environment:action`](../yaml/README.md#environmentaction) is set. Can be `start`, `prepare`, or `stop`. | +| `CI_ENVIRONMENT_NAME` | 8.15 | all | The name of the environment for this job. Available if [`environment:name`](../yaml/index.md#environmentname) is set. | +| `CI_ENVIRONMENT_SLUG` | 8.15 | all | The simplified version of the environment name, suitable for inclusion in DNS, URLs, Kubernetes labels, and so on. Available if [`environment:name`](../yaml/index.md#environmentname) is set. The slug is [truncated to 24 characters](https://gitlab.com/gitlab-org/gitlab/-/issues/20941). | +| `CI_ENVIRONMENT_URL` | 9.3 | all | The URL of the environment for this job. Available if [`environment:url`](../yaml/index.md#environmenturl) is set. | +| `CI_ENVIRONMENT_ACTION` | 13.11 | all | The action annotation specified for this job's environment. Available if [`environment:action`](../yaml/index.md#environmentaction) is set. Can be `start`, `prepare`, or `stop`. | | `CI_ENVIRONMENT_TIER` | 14.0 | all | The [deployment tier of the environment](../environments/index.md#deployment-tier-of-environments) for this job. | | `CI_HAS_OPEN_REQUIREMENTS` | 13.1 | all | Only available if the pipeline's project has an open [requirement](../../user/project/requirements/index.md). `true` when available. | | `CI_JOB_ID` | 9.0 | all | The internal ID of the job, unique across all jobs in the GitLab instance. | @@ -61,13 +61,13 @@ There are also [Kubernetes-specific deployment variables](../../user/project/clu | `CI_JOB_MANUAL` | 8.12 | all | `true` if a job was started manually. | | `CI_JOB_NAME` | 9.0 | 0.5 | The name of the job. | | `CI_JOB_STAGE` | 9.0 | 0.5 | The name of the job's stage. | -| `CI_JOB_STATUS` | all | 13.5 | The status of the job as each runner stage is executed. Use with [`after_script`](../yaml/README.md#after_script). Can be `success`, `failed`, or `canceled`. | +| `CI_JOB_STATUS` | all | 13.5 | The status of the job as each runner stage is executed. Use with [`after_script`](../yaml/index.md#after_script). Can be `success`, `failed`, or `canceled`. | | `CI_JOB_TOKEN` | 9.0 | 1.2 | A token to authenticate with [certain API endpoints](../../api/index.md#gitlab-cicd-job-token). The token is valid as long as the job is running. | | `CI_JOB_URL` | 11.1 | 0.5 | The job details URL. | | `CI_JOB_STARTED_AT` | 13.10 | all | The UTC datetime when a job started, in [ISO 8601](https://tools.ietf.org/html/rfc3339#appendix-A) format. | | `CI_KUBERNETES_ACTIVE` | 13.0 | all | Only available if the pipeline has a Kubernetes cluster available for deployments. `true` when available. | -| `CI_NODE_INDEX` | 11.5 | all | The index of the job in the job set. Only available if the job uses [`parallel`](../yaml/README.md#parallel). | -| `CI_NODE_TOTAL` | 11.5 | all | The total number of instances of this job running in parallel. Set to `1` if the job does not use [`parallel`](../yaml/README.md#parallel). | +| `CI_NODE_INDEX` | 11.5 | all | The index of the job in the job set. Only available if the job uses [`parallel`](../yaml/index.md#parallel). | +| `CI_NODE_TOTAL` | 11.5 | all | The total number of instances of this job running in parallel. Set to `1` if the job does not use [`parallel`](../yaml/index.md#parallel). | | `CI_OPEN_MERGE_REQUESTS` | 13.8 | all | A comma-separated list of up to four merge requests that use the current branch and project as the merge request source. Only available in branch and merge request pipelines if the branch has an associated merge request. For example, `gitlab-org/gitlab!333,gitlab-org/gitlab-foss!11`. | | `CI_PAGES_DOMAIN` | 11.8 | all | The configured domain that hosts GitLab Pages. | | `CI_PAGES_URL` | 11.8 | all | The URL for a GitLab Pages site. Always a subdomain of `CI_PAGES_DOMAIN`. | diff --git a/doc/ci/variables/where_variables_can_be_used.md b/doc/ci/variables/where_variables_can_be_used.md index ff89df04932..beb19c8beea 100644 --- a/doc/ci/variables/where_variables_can_be_used.md +++ b/doc/ci/variables/where_variables_can_be_used.md @@ -149,7 +149,7 @@ In the case of `after_script` scripts, they can: - Not use variables defined in `before_script` and `script`. These restrictions exist because `after_script` scripts are executed in a -[separated shell context](../yaml/README.md#after_script). +[separated shell context](../yaml/index.md#after_script). ## Persisted variables diff --git a/doc/ci/yaml/README.md b/doc/ci/yaml/README.md index 73f742ed245..5ab8653dc35 100644 --- a/doc/ci/yaml/README.md +++ b/doc/ci/yaml/README.md @@ -1,4829 +1,8 @@ --- -stage: Verify -group: Pipeline Execution -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' --- - - -# Keyword reference for the .gitlab-ci.yml file **(FREE)** - - +This document was moved to [another location](index.md). -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/index.md). -- For a collection of examples, see [GitLab CI/CD Examples](../examples/index.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). - -When you are editing your `.gitlab-ci.yml` file, you can validate it with the -[CI Lint](../lint.md) tool. - -## Job keywords - -A job is defined as a list of keywords that define the job's behavior. - -The keywords available for jobs are: - -| Keyword | Description | -| :-----------------------------------|:------------| -| [`after_script`](#after_script) | Override a set of commands that are executed after job. | -| [`allow_failure`](#allow_failure) | Allow job to fail. A failed job does not cause the pipeline to fail. | -| [`artifacts`](#artifacts) | List of files and directories to attach to a job on success. | -| [`before_script`](#before_script) | Override a set of commands that are executed before job. | -| [`cache`](#cache) | List of files that should be cached between subsequent runs. | -| [`coverage`](#coverage) | Code coverage settings for a given job. | -| [`dependencies`](#dependencies) | Restrict which artifacts are passed to a specific job by providing a list of jobs to fetch artifacts from. | -| [`environment`](#environment) | Name of an environment to which the job deploys. | -| [`except`](#only--except) | Control when jobs are not created. | -| [`extends`](#extends) | Configuration entries that this job inherits from. | -| [`image`](#image) | Use Docker images. | -| [`include`](#include) | Include external YAML files. | -| [`inherit`](#inherit) | Select which global defaults all jobs inherit. | -| [`interruptible`](#interruptible) | Defines if a job can be canceled when made redundant by a newer run. | -| [`needs`](#needs) | Execute jobs earlier than the stage ordering. | -| [`only`](#only--except) | Control when jobs are created. | -| [`pages`](#pages) | Upload the result of a job to use with GitLab Pages. | -| [`parallel`](#parallel) | How many instances of a job should be run in parallel. | -| [`release`](#release) | Instructs the runner to generate a [release](../../user/project/releases/index.md) object. | -| [`resource_group`](#resource_group) | Limit job concurrency. | -| [`retry`](#retry) | When and how many times a job can be auto-retried in case of a failure. | -| [`rules`](#rules) | List of conditions to evaluate and determine selected attributes of a job, and whether or not it's created. | -| [`script`](#script) | Shell script that is executed by a runner. | -| [`secrets`](#secrets) | The CI/CD secrets the job needs. | -| [`services`](#services) | Use Docker services images. | -| [`stage`](#stage) | Defines a job stage. | -| [`tags`](#tags) | List of tags that are used to select a runner. | -| [`timeout`](#timeout) | Define a custom job-level timeout that takes precedence over the project-wide setting. | -| [`trigger`](#trigger) | Defines a downstream pipeline trigger. | -| [`variables`](#variables) | Define job variables on a job level. | -| [`when`](#when) | When to run job. | - -### Unavailable names for jobs - -You can't use these keywords as job names: - -- `image` -- `services` -- `stages` -- `types` -- `before_script` -- `after_script` -- `variables` -- `cache` -- `include` - -### Custom default keyword values - -You can set global defaults for some keywords. Jobs that do not define one or more -of the listed keywords use the value defined in the `default:` section. - -These job keywords can be defined inside a `default:` section: - -- [`after_script`](#after_script) -- [`artifacts`](#artifacts) -- [`before_script`](#before_script) -- [`cache`](#cache) -- [`image`](#image) -- [`interruptible`](#interruptible) -- [`retry`](#retry) -- [`services`](#services) -- [`tags`](#tags) -- [`timeout`](#timeout) - -The following example sets the `ruby:3.0` image as the default for all jobs in the pipeline. -The `rspec 2.7` job does not use the default, because it overrides the default with -a job-specific `image:` section: - -```yaml -default: - image: ruby:3.0 - -rspec: - script: bundle exec rspec - -rspec 2.7: - image: ruby:2.7 - script: bundle exec rspec -``` - -## Global keywords - -Some keywords are not defined in a job. These keywords control pipeline behavior -or import additional pipeline configuration: - -| Keyword | Description | -|-------------------------|:------------| -| [`stages`](#stages) | The names and order of the pipeline stages. | -| [`workflow`](#workflow) | Control what types of pipeline run. | -| [`include`](#include) | Import configuration from other YAML files. | - -### `stages` - -Use `stages` to define stages that contain groups of jobs. `stages` is defined globally -for the pipeline. Use [`stage`](#stage) in a job to define which stage the job is -part of. - -The order of the `stages` items defines the execution order for jobs: - -- Jobs in the same stage run in parallel. -- Jobs in the next stage run after the jobs from the previous stage complete successfully. - -For example: - -```yaml -stages: - - build - - test - - deploy -``` - -1. All jobs in `build` execute in parallel. -1. If all jobs in `build` succeed, the `test` jobs execute in parallel. -1. If all jobs in `test` succeed, the `deploy` jobs execute in parallel. -1. If all jobs in `deploy` succeed, the pipeline is marked as `passed`. - -If any job fails, the pipeline is marked as `failed` and jobs in later stages do not -start. Jobs in the current stage are not stopped and continue to run. - -If no `stages` are defined in the `.gitlab-ci.yml` file, then `build`, `test` and `deploy` -are the default pipeline stages. - -If a job does not specify a [`stage`](#stage), the job is assigned the `test` stage. - -If a stage is defined, but no jobs use it, the stage is not visible in the pipeline. This is -useful for [compliance pipeline configuration](../../user/project/settings/index.md#compliance-pipeline-configuration) -because: - -- Stages can be defined in the compliance configuration but remain hidden if not used. -- The defined stages become visible when developers use them in job definitions. - -To make a job start earlier and ignore the stage order, use -the [`needs`](#needs) keyword. - -### `workflow` - -> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/29654) in GitLab 12.5 - -Use `workflow:` to determine whether or not a pipeline is created. -Define this keyword at the top level, with a single `rules:` keyword that -is similar to [`rules:` defined in jobs](#rules). - -You can use the [`workflow:rules` templates](#workflowrules-templates) to import -a preconfigured `workflow: rules` entry. - -`workflow: rules` accepts these keywords: - -- [`if`](#rulesif): Check this rule to determine when to run a pipeline. -- [`when`](#when): Specify what to do when the `if` rule evaluates to true. - - To run a pipeline, set to `always`. - - To prevent pipelines from running, set to `never`. -- [`variables`](#workflowrulesvariables): If not defined, uses the [variables defined elsewhere](#variables). - -When no rules evaluate to true, the pipeline does not run. - -Some example `if` clauses for `workflow: rules`: - -| Example rules | Details | -|------------------------------------------------------|-----------------------------------------------------------| -| `if: '$CI_PIPELINE_SOURCE == "merge_request_event"'` | Control when merge request pipelines run. | -| `if: '$CI_PIPELINE_SOURCE == "push"'` | Control when both branch pipelines and tag pipelines run. | -| `if: $CI_COMMIT_TAG` | Control when tag pipelines run. | -| `if: $CI_COMMIT_BRANCH` | Control when branch pipelines run. | - -See the [common `if` clauses for `rules`](../jobs/job_control.md#common-if-clauses-for-rules) for more examples. - -In the following example, pipelines run for all `push` events (changes to -branches and new tags). Pipelines for push events with `-draft` in the commit message -don't run, because they are set to `when: never`. Pipelines for schedules or merge requests -don't run either, because no rules evaluate to true for them: - -```yaml -workflow: - rules: - - if: $CI_COMMIT_MESSAGE =~ /-draft$/ - when: never - - if: '$CI_PIPELINE_SOURCE == "push"' -``` - -This example has strict rules, and pipelines do **not** run in any other case. - -Alternatively, all of the rules can be `when: never`, with a final -`when: always` rule. Pipelines that match the `when: never` rules do not run. -All other pipeline types run: - -```yaml -workflow: - rules: - - if: '$CI_PIPELINE_SOURCE == "schedule"' - when: never - - if: '$CI_PIPELINE_SOURCE == "push"' - when: never - - when: always -``` - -This example prevents pipelines for schedules or `push` (branches and tags) pipelines. -The final `when: always` rule runs all other pipeline types, **including** merge -request pipelines. - -If your rules match both branch pipelines and merge request pipelines, -[duplicate pipelines](../jobs/job_control.md#avoid-duplicate-pipelines) can occur. - -#### `workflow:rules:variables` - -> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/294232) in GitLab 13.11. -> - [Feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/issues/300997) in GitLab 14.1. - -You can use [`variables`](#variables) in `workflow:rules:` to define variables for specific pipeline conditions. - -For example: - -```yaml -variables: - DEPLOY_VARIABLE: "default-deploy" - -workflow: - rules: - - if: $CI_COMMIT_REF_NAME == $CI_DEFAULT_BRANCH - variables: - DEPLOY_VARIABLE: "deploy-production" # Override globally-defined DEPLOY_VARIABLE - - if: $CI_COMMIT_REF_NAME =~ /feature/ - variables: - IS_A_FEATURE: "true" # Define a new variable. - - when: always # Run the pipeline in other cases - -job1: - variables: - DEPLOY_VARIABLE: "job1-default-deploy" - rules: - - if: $CI_COMMIT_REF_NAME == $CI_DEFAULT_BRANCH - variables: # Override DEPLOY_VARIABLE defined - DEPLOY_VARIABLE: "job1-deploy-production" # at the job level. - - when: on_success # Run the job in other cases - script: - - echo "Run script with $DEPLOY_VARIABLE as an argument" - - echo "Run another script if $IS_A_FEATURE exists" - -job2: - script: - - echo "Run script with $DEPLOY_VARIABLE as an argument" - - echo "Run another script if $IS_A_FEATURE exists" -``` - -When the branch is the default branch: - -- job1's `DEPLOY_VARIABLE` is `job1-deploy-production`. -- job2's `DEPLOY_VARIABLE` is `deploy-production`. - -When the branch is `feature`: - -- job1's `DEPLOY_VARIABLE` is `job1-default-deploy`, and `IS_A_FEATURE` is `true`. -- job2's `DEPLOY_VARIABLE` is `default-deploy`, and `IS_A_FEATURE` is `true`. - -When the branch is something else: - -- job1's `DEPLOY_VARIABLE` is `job1-default-deploy`. -- job2's `DEPLOY_VARIABLE` is `default-deploy`. - -#### `workflow:rules` templates - -> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/217732) in GitLab 13.0. - -GitLab provides templates that set up `workflow: rules` -for common scenarios. These templates help prevent duplicate pipelines. - -The [`Branch-Pipelines` template](https://gitlab.com/gitlab-org/gitlab/-/tree/master/lib/gitlab/ci/templates/Workflows/Branch-Pipelines.gitlab-ci.yml) -makes your pipelines run for branches and tags. - -Branch pipeline status is displayed in merge requests that use the branch -as a source. However, this pipeline type does not support any features offered by -[merge request pipelines](../merge_request_pipelines/), like -[pipelines for merged results](../merge_request_pipelines/pipelines_for_merged_results/index.md) -or [merge trains](../merge_request_pipelines/pipelines_for_merged_results/merge_trains/). -This template intentionally avoids those features. - -To [include](#include) it: - -```yaml -include: - - template: 'Workflows/Branch-Pipelines.gitlab-ci.yml' -``` - -The [`MergeRequest-Pipelines` template](https://gitlab.com/gitlab-org/gitlab/-/tree/master/lib/gitlab/ci/templates/Workflows/MergeRequest-Pipelines.gitlab-ci.yml) -makes your pipelines run for the default branch, tags, and -all types of merge request pipelines. Use this template if you use any of the -the [pipelines for merge requests features](../merge_request_pipelines/). - -To [include](#include) it: - -```yaml -include: - - template: 'Workflows/MergeRequest-Pipelines.gitlab-ci.yml' -``` - -#### Switch between branch pipelines and merge request pipelines - -> [Introduced in](https://gitlab.com/gitlab-org/gitlab/-/issues/201845) GitLab 13.8. - -To make the pipeline switch from branch pipelines to merge request pipelines after -a merge request is created, add a `workflow: rules` section to your `.gitlab-ci.yml` file. - -If you use both pipeline types at the same time, [duplicate pipelines](../jobs/job_control.md#avoid-duplicate-pipelines) -might run at the same time. To prevent duplicate pipelines, use the -[`CI_OPEN_MERGE_REQUESTS` variable](../variables/predefined_variables.md). - -The following example is for a project that runs branch and merge request pipelines only, -but does not run pipelines for any other case. It runs: - -- Branch pipelines when a merge request is not open for the branch. -- Merge request pipelines when a merge request is open for the branch. - -```yaml -workflow: - rules: - - if: '$CI_PIPELINE_SOURCE == "merge_request_event"' - - if: '$CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS' - when: never - - if: '$CI_COMMIT_BRANCH' -``` - -If the pipeline is triggered by: - -- A merge request, run a merge request pipeline. For example, a merge request pipeline - can be triggered by a push to a branch with an associated open merge request. -- A change to a branch, but a merge request is open for that branch, do not run a branch pipeline. -- A change to a branch, but without any open merge requests, run a branch pipeline. - -You can also add a rule to an existing `workflow` section to switch from branch pipelines -to merge request pipelines when a merge request is created. - -Add this rule to the top of the `workflow` section, followed by the other rules that -were already present: - -```yaml -workflow: - rules: - - if: $CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS && $CI_PIPELINE_SOURCE == "push" - when: never - - ... # Previously defined workflow rules here -``` - -[Triggered pipelines](../triggers/index.md) that run on a branch have a `$CI_COMMIT_BRANCH` -set and could be blocked by a similar rule. Triggered pipelines have a pipeline source -of `trigger` or `pipeline`, so `&& $CI_PIPELINE_SOURCE == "push"` ensures the rule -does not block triggered pipelines. - -### `include` - -> [Moved](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/42861) to GitLab Free in 11.4. - -Use `include` to include external YAML files in your CI/CD configuration. -You can break down one long `gitlab-ci.yml` file into multiple files to increase readability, -or reduce duplication of the same configuration in multiple places. - -You can also store template files in a central repository and `include` them in projects. - -`include` requires the external YAML file to have the extensions `.yml` or `.yaml`, -otherwise the external file is not included. - -You can't use [YAML anchors](#anchors) across different YAML files sourced by `include`. -You can only refer to anchors in the same file. To reuse configuration from different -YAML files, use [`!reference` tags](#reference-tags) or the [`extends` keyword](#extends). - -`include` supports the following inclusion methods: - -| Keyword | Method | -|:--------------------------------|:------------------------------------------------------------------| -| [`local`](#includelocal) | Include a file from the local project repository. | -| [`file`](#includefile) | Include a file from a different project repository. | -| [`remote`](#includeremote) | Include a file from a remote URL. Must be publicly accessible. | -| [`template`](#includetemplate) | Include templates that are provided by GitLab. | - -When the pipeline starts, the `.gitlab-ci.yml` file configuration included by all methods is evaluated. -The configuration is a snapshot in time and persists in the database. GitLab does not reflect any changes to -the referenced `.gitlab-ci.yml` file configuration until the next pipeline starts. - -The `include` files are: - -- Deep merged with those in the `.gitlab-ci.yml` file. -- Always evaluated first and merged with the content of the `.gitlab-ci.yml` file, - regardless of the position of the `include` keyword. - -NOTE: -Use merging to customize and override included CI/CD configurations with local -configurations. Local configurations in the `.gitlab-ci.yml` file override included configurations. - -#### Variables with `include` **(FREE SELF)** - -> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/284883) in GitLab 13.8. -> - [Feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/issues/294294) in GitLab 13.9. - -You can [use some predefined variables in `include` sections](../variables/where_variables_can_be_used.md#gitlab-ciyml-file) -in your `.gitlab-ci.yml` file: - -```yaml -include: - project: '$CI_PROJECT_PATH' - file: '.compliance-gitlab-ci.yml' -``` - -For an example of how you can include these predefined variables, and the variables' impact on CI/CD jobs, -see this [CI/CD variable demo](https://youtu.be/4XR8gw3Pkos). - -#### `include:local` - -Use `include:local` to include a file that is in the same repository as the `.gitlab-ci.yml` file. -Use a full path relative to the root directory (`/`). - -If you use `include:local`, make sure that both the `.gitlab-ci.yml` file and the local file -are on the same branch. - -You can't include local files through Git submodules paths. - -All [nested includes](#nested-includes) are executed in the scope of the same project, -so it's possible to use local, project, remote, or template includes. - -Example: - -```yaml -include: - - local: '/templates/.gitlab-ci-template.yml' -``` - -You can also use shorter syntax to define the path: - -```yaml -include: '.gitlab-ci-production.yml' -``` - -Use local includes instead of symbolic links. - -##### `include:local` with wildcard file paths - -> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/25921) in GitLab 13.11. -> - [Deployed behind a feature flag](../../user/feature_flags.md), disabled by default. -> - [Enabled by default](https://gitlab.com/gitlab-org/gitlab/-/issues/327315) in GitLab 13.12. -> - Enabled on GitLab.com. -> - Recommended for production use. -> - For GitLab self-managed instances, GitLab administrators can opt to disable it. **(CORE ONLY)** - -There can be -[risks when disabling released features](../../user/feature_flags.md#risks-when-disabling-released-features). -Refer to this feature's version history for more details. - -You can use wildcard paths (`*` and `**`) with `include:local`. - -Example: - -```yaml -include: 'configs/*.yml' -``` - -When the pipeline runs, GitLab: - -- Adds all `.yml` files in the `configs` directory into the pipeline configuration. -- Does not add `.yml` files in subfolders of the `configs` directory. To allow this, - add the following configuration: - - ```yaml - # This matches all `.yml` files in `configs` and any subfolder in it. - include: 'configs/**.yml' - - # This matches all `.yml` files only in subfolders of `configs`. - include: 'configs/**/*.yml' - ``` - -The wildcard file paths feature is under development but ready for production use. -It is deployed behind a feature flag that is **enabled by default**. -[GitLab administrators with access to the GitLab Rails console](../../administration/feature_flags.md) -can opt to disable it. - -To enable it: - -```ruby -Feature.enable(:ci_wildcard_file_paths) -``` - -To disable it: - -```ruby -Feature.disable(:ci_wildcard_file_paths) -``` - -#### `include:file` - -> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/53903) in GitLab 11.7. - -To include files from another private project on the same GitLab instance, -use `include:file`. You can use `include:file` in combination with `include:project` only. -Use a full path, relative to the root directory (`/`). - -For example: - -```yaml -include: - - project: 'my-group/my-project' - file: '/templates/.gitlab-ci-template.yml' -``` - -You can also specify a `ref`. If you do not specify a value, the ref defaults to the `HEAD` of the project: - -```yaml -include: - - project: 'my-group/my-project' - ref: main - file: '/templates/.gitlab-ci-template.yml' - - - project: 'my-group/my-project' - ref: v1.0.0 - file: '/templates/.gitlab-ci-template.yml' - - - project: 'my-group/my-project' - ref: 787123b47f14b552955ca2786bc9542ae66fee5b # Git SHA - file: '/templates/.gitlab-ci-template.yml' -``` - -All [nested includes](#nested-includes) are executed in the scope of the target project. -You can use local (relative to target project), project, remote, or template includes. - -##### Multiple files from a project - -> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/26793) in GitLab 13.6. -> - [Feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/issues/271560) in GitLab 13.8. - -You can include multiple files from the same project: - -```yaml -include: - - project: 'my-group/my-project' - ref: main - file: - - '/templates/.builds.yml' - - '/templates/.tests.yml' -``` - -#### `include:remote` - -Use `include:remote` with a full URL to include a file from a different location. -The remote file must be publicly accessible by an HTTP/HTTPS `GET` request, because -authentication in the remote URL is not supported. For example: - -```yaml -include: - - remote: 'https://gitlab.com/example-project/-/raw/main/.gitlab-ci.yml' -``` - -All [nested includes](#nested-includes) execute without context as a public user, -so you can only `include` public projects or templates. - -#### `include:template` - -> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/53445) in GitLab 11.7. - -Use `include:template` to include `.gitlab-ci.yml` templates that are -[shipped with GitLab](https://gitlab.com/gitlab-org/gitlab/-/tree/master/lib/gitlab/ci/templates). - -For example: - -```yaml -# File sourced from the GitLab template collection -include: - - template: Auto-DevOps.gitlab-ci.yml -``` - -Multiple `include:template` files: - -```yaml -include: - - template: Android-Fastlane.gitlab-ci.yml - - template: Auto-DevOps.gitlab-ci.yml -``` - -All [nested includes](#nested-includes) are executed only with the permission of the user, -so it's possible to use project, remote or template includes. - -#### Nested includes - -> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/56836) in GitLab 11.9. - -Use nested includes to compose a set of includes. - -You can have up to 100 includes, but you can't have duplicate includes. - -In [GitLab 12.4](https://gitlab.com/gitlab-org/gitlab/-/issues/28212) and later, the time limit -to resolve all files is 30 seconds. - -#### Additional `includes` examples - -View [additional `includes` examples](includes.md). - -## Keyword details - -The following topics explain how to use keywords to configure CI/CD pipelines. - -### `image` - -Use `image` to specify [a Docker image](../docker/using_docker_images.md#what-is-an-image) to use for the job. - -For: - -- Usage examples, see [Define `image` in the `.gitlab-ci.yml` file](../docker/using_docker_images.md#define-image-in-the-gitlab-ciyml-file). -- Detailed usage information, refer to [Docker integration](../docker/index.md) documentation. - -#### `image:name` - -An [extended Docker configuration option](../docker/using_docker_images.md#extended-docker-configuration-options). - -For more information, see [Available settings for `image`](../docker/using_docker_images.md#available-settings-for-image). - -#### `image:entrypoint` - -An [extended Docker configuration option](../docker/using_docker_images.md#extended-docker-configuration-options). - -For more information, see [Available settings for `image`](../docker/using_docker_images.md#available-settings-for-image). - -#### `services` - -Use `services` to specify a [service Docker image](../services/index.md), linked to a base image specified in [`image`](#image). - -For: - -- Usage examples, see [Define `services` in the `.gitlab-ci.yml` file](../services/index.md#define-services-in-the-gitlab-ciyml-file). -- Detailed usage information, refer to [Docker integration](../docker/index.md) documentation. -- Example services, see [GitLab CI/CD Services](../services/index.md). - -##### `services:name` - -An [extended Docker configuration option](../docker/using_docker_images.md#extended-docker-configuration-options). - -For more information, see [Available settings for `services`](../services/index.md#available-settings-for-services). - -##### `services:alias` - -An [extended Docker configuration option](../docker/using_docker_images.md#extended-docker-configuration-options). - -For more information, see [Available settings for `services`](../services/index.md#available-settings-for-services). - -##### `services:entrypoint` - -An [extended Docker configuration option](../docker/using_docker_images.md#extended-docker-configuration-options). - -For more information, see [Available settings for `services`](../services/index.md#available-settings-for-services). - -##### `services:command` - -An [extended Docker configuration option](../docker/using_docker_images.md#extended-docker-configuration-options). - -For more information, see [Available settings for `services`](../services/index.md#available-settings-for-services). - -### `script` - -Use `script` to specify a shell script for the runner to execute. - -All jobs except [trigger jobs](#trigger) require a `script` keyword. - -For example: - -```yaml -job: - script: "bundle exec rspec" -``` - -You can use [YAML anchors with `script`](#yaml-anchors-for-scripts). - -The `script` keyword can also contain several commands in an array: - -```yaml -job: - script: - - uname -a - - bundle exec rspec -``` - -Sometimes, `script` commands must be wrapped in single or double quotes. -For example, commands that contain a colon (`:`) must be wrapped in single quotes (`'`). -The YAML parser needs to interpret the text as a string rather than -a "key: value" pair. - -For example, this script uses a colon: - -```yaml -job: - script: - - curl --request POST --header 'Content-Type: application/json' "https://gitlab/api/v4/projects" -``` - -To be considered valid YAML, you must wrap the entire command in single quotes. If -the command already uses single quotes, you should change them to double quotes (`"`) -if possible: - -```yaml -job: - script: - - 'curl --request POST --header "Content-Type: application/json" "https://gitlab/api/v4/projects"' -``` - -You can verify the syntax is valid with the [CI Lint](../lint.md) tool. - -Be careful when using these characters as well: - -- `{`, `}`, `[`, `]`, `,`, `&`, `*`, `#`, `?`, `|`, `-`, `<`, `>`, `=`, `!`, `%`, `@`, `` ` ``. - -If any of the script commands return an exit code other than zero, the job -fails and further commands are not executed. Store the exit code in a variable to -avoid this behavior: - -```yaml -job: - script: - - false || exit_code=$? - - if [ $exit_code -ne 0 ]; then echo "Previous command failed"; fi; -``` - -#### `before_script` - -Use `before_script` to define an array of commands that should run before each job, -but after [artifacts](#artifacts) are restored. - -Scripts you specify in `before_script` are concatenated with any scripts you specify -in the main [`script`](#script). The combine scripts execute together in a single shell. - -You can overwrite a globally-defined `before_script` if you define it in a job: - -```yaml -default: - before_script: - - echo "Execute this script in all jobs that don't already have a before_script section." - -job1: - script: - - echo "This script executes after the global before_script." - -job: - before_script: - - echo "Execute this script instead of the global before_script." - script: - - echo "This script executes after the job's `before_script`" -``` - -You can use [YAML anchors with `before_script`](#yaml-anchors-for-scripts). - -#### `after_script` - -Use `after_script` to define an array of commands that run after each job, -including failed jobs. - -If a job times out or is cancelled, the `after_script` commands do not execute. -An [issue](https://gitlab.com/gitlab-org/gitlab/-/issues/15603) exists to support -executing `after_script` commands for timed-out or cancelled jobs. - -Scripts you specify in `after_script` execute in a new shell, separate from any -`before_script` or `script` scripts. As a result, they: - -- Have a current working directory set back to the default. -- Have no access to changes done by scripts defined in `before_script` or `script`, including: - - Command aliases and variables exported in `script` scripts. - - Changes outside of the working tree (depending on the runner executor), like - software installed by a `before_script` or `script` script. -- Have a separate timeout, which is hard coded to 5 minutes. See the - [related issue](https://gitlab.com/gitlab-org/gitlab-runner/-/issues/2716) for details. -- Don't affect the job's exit code. If the `script` section succeeds and the - `after_script` times out or fails, the job exits with code `0` (`Job Succeeded`). - -```yaml -default: - after_script: - - echo "Execute this script in all jobs that don't already have an after_script section." - -job1: - script: - - echo "This script executes first. When it completes, the global after_script executes." - -job: - script: - - echo "This script executes first. When it completes, the job's `after_script` executes." - after_script: - - echo "Execute this script instead of the global after_script." -``` - -You can use [YAML anchors with `after_script`](#yaml-anchors-for-scripts). - -#### Script syntax - -You can use syntax in [`script`](README.md#script) sections to: - -- [Split long commands](script.md#split-long-commands) into multiline commands. -- [Use color codes](script.md#add-color-codes-to-script-output) to make job logs easier to review. -- [Create custom collapsible sections](../jobs/index.md#custom-collapsible-sections) - to simplify job log output. - -### `stage` - -Use `stage` to define which stage a job runs in. Jobs in the same -`stage` can execute in parallel (subject to [certain conditions](#use-your-own-runners)). - -Jobs without a `stage` entry use the `test` stage by default. If you do not define -[`stages`](#stages) in the pipeline, you can use the 5 default stages, which execute in -this order: - -- [`.pre`](#pre-and-post) -- `build` -- `test` -- `deploy` -- [`.post`](#pre-and-post) -For example: - -```yaml -stages: - - build - - test - - deploy - -job 0: - stage: .pre - script: make something useful before build stage - -job 1: - stage: build - script: make build dependencies - -job 2: - stage: build - script: make build artifacts - -job 3: - stage: test - script: make test - -job 4: - stage: deploy - script: make deploy - -job 5: - stage: .post - script: make something useful at the end of pipeline -``` - -#### Use your own runners - -When you use your own runners, each runner runs only one job at a time by default. -Jobs can run in parallel if they run on different runners. - -If you have only one runner, jobs can run in parallel if the runner's -[`concurrent` setting](https://docs.gitlab.com/runner/configuration/advanced-configuration.html#the-global-section) -is greater than `1`. - -#### `.pre` and `.post` - -> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/31441) in GitLab 12.4. - -Use `pre` and `post` for jobs that need to run first or last in a pipeline. - -- `.pre` is guaranteed to always be the first stage in a pipeline. -- `.post` is guaranteed to always be the last stage in a pipeline. - -User-defined stages are executed after `.pre` and before `.post`. - -You must have a job in at least one stage other than `.pre` or `.post`. - -You can't change the order of `.pre` and `.post`, even if you define them out of order in the `.gitlab-ci.yml` file. -For example, the following configurations are equivalent: - -```yaml -stages: - - .pre - - a - - b - - .post -``` - -```yaml -stages: - - a - - .pre - - b - - .post -``` - -```yaml -stages: - - a - - b -``` - -### `extends` - -> Introduced in GitLab 11.3. - -Use `extends` to reuse configuration sections. It's an alternative to [YAML anchors](#anchors) -and is a little more flexible and readable. You can use `extends` to reuse configuration -from [included configuration files](#use-extends-and-include-together). - -In the following example, the `rspec` job uses the configuration from the `.tests` template job. -GitLab: - -- Performs a reverse deep merge based on the keys. -- Merges the `.tests` content with the `rspec` job. -- Doesn't merge the values of the keys. - -```yaml -.tests: - script: rake test - stage: test - only: - refs: - - branches - -rspec: - extends: .tests - script: rake rspec - only: - variables: - - $RSPEC -``` - -The result is this `rspec` job: - -```yaml -rspec: - script: rake rspec - stage: test - only: - refs: - - branches - variables: - - $RSPEC -``` - -`.tests` in this example is a [hidden job](#hide-jobs), but it's -possible to extend configuration from regular jobs as well. - -`extends` supports multi-level inheritance. You should avoid using more than three levels, -but you can use as many as eleven. The following example has two levels of inheritance: - -```yaml -.tests: - rules: - - if: $CI_PIPELINE_SOURCE == "push" - -.rspec: - extends: .tests - script: rake rspec - -rspec 1: - variables: - RSPEC_SUITE: '1' - extends: .rspec - -rspec 2: - variables: - RSPEC_SUITE: '2' - extends: .rspec - -spinach: - extends: .tests - script: rake spinach -``` - -In GitLab 12.0 and later, it's also possible to use multiple parents for -`extends`. - -#### Merge details - -You can use `extends` to merge hashes but not arrays. -The algorithm used for merge is "closest scope wins," so -keys from the last member always override anything defined on other -levels. For example: - -```yaml -.only-important: - variables: - URL: "http://my-url.internal" - IMPORTANT_VAR: "the details" - rules: - - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH - - if: $CI_COMMIT_BRANCH == "stable" - tags: - - production - script: - - echo "Hello world!" - -.in-docker: - variables: - URL: "http://docker-url.internal" - tags: - - docker - image: alpine - -rspec: - variables: - GITLAB: "is-awesome" - extends: - - .only-important - - .in-docker - script: - - rake rspec -``` - -The result is this `rspec` job: - -```yaml -rspec: - variables: - URL: "http://docker-url.internal" - IMPORTANT_VAR: "the details" - GITLAB: "is-awesome" - rules: - - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH - - if: $CI_COMMIT_BRANCH == "stable" - tags: - - docker - image: alpine - script: - - rake rspec -``` - -In this example: - -- The `variables` sections merge, but `URL: "http://docker-url.internal"` overwrites `URL: "http://my-url.internal"`. -- `tags: ['docker']` overwrites `tags: ['production']`. -- `script` does not merge, but `script: ['rake rspec']` overwrites - `script: ['echo "Hello world!"']`. You can use [YAML anchors](#anchors) to merge arrays. - -#### Use `extends` and `include` together - -To reuse configuration from different configuration files, -combine `extends` and [`include`](#include). - -In the following example, a `script` is defined in the `included.yml` file. -Then, in the `.gitlab-ci.yml` file, `extends` refers -to the contents of the `script`: - -- `included.yml`: - - ```yaml - .template: - script: - - echo Hello! - ``` - -- `.gitlab-ci.yml`: - - ```yaml - include: included.yml - - useTemplate: - image: alpine - extends: .template - ``` - -### `rules` - -> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/27863) in GitLab 12.3. - -Use `rules` to include or exclude jobs in pipelines. - -Rules are evaluated *in order* until the first match. When a match is found, the job -is either included or excluded from the pipeline, depending on the configuration. - -`rules` replaces [`only/except`](#only--except) and they can't be used together -in the same job. If you configure one job to use both keywords, the GitLab returns -a `key may not be used with rules` error. - -`rules` accepts an array of rules defined with: - -- `if` -- `changes` -- `exists` -- `allow_failure` -- `variables` -- `when` - -You can combine multiple keywords together for [complex rules](../jobs/job_control.md#complex-rules). - -The job is added to the pipeline: - -- If an `if`, `changes`, or `exists` rule matches and also has `when: on_success` (default), - `when: delayed`, or `when: always`. -- If a rule is reached that is only `when: on_success`, `when: delayed`, or `when: always`. - -The job is not added to the pipeline: - -- If no rules match. -- If a rule matches and has `when: never`. - -#### `rules:if` - -Use `rules:if` clauses to specify when to add a job to a pipeline: - -- If an `if` statement is true, add the job to the pipeline. -- If an `if` statement is true, but it's combined with `when: never`, do not add the job to the pipeline. -- If no `if` statements are true, do not add the job to the pipeline. - -`if:` clauses are evaluated based on the values of [predefined CI/CD variables](../variables/predefined_variables.md) -or [custom CI/CD variables](../variables/index.md#custom-cicd-variables). - -**Keyword type**: Job-specific and pipeline-specific. You can use it as part of a job -to configure the job behavior, or with [`workflow`](#workflow) to configure the pipeline behavior. - -**Possible inputs**: A [CI/CD variable expression](../jobs/job_control.md#cicd-variable-expressions). - -**Example of `rules:if`**: - -```yaml -job: - script: echo "Hello, Rules!" - rules: - - if: '$CI_MERGE_REQUEST_SOURCE_BRANCH_NAME =~ /^feature/ && $CI_MERGE_REQUEST_TARGET_BRANCH_NAME != $CI_DEFAULT_BRANCH' - when: never - - if: '$CI_MERGE_REQUEST_SOURCE_BRANCH_NAME =~ /^feature/' - when: manual - allow_failure: true - - if: '$CI_MERGE_REQUEST_SOURCE_BRANCH_NAME' -``` - -**Additional details**: - -- If a rule matches and has no `when` defined, the rule uses the `when` - defined for the job, which defaults to `on_success` if not defined. -- You can define `when` once per rule, or once at the job-level, which applies to - all rules. You can't mix `when` at the job-level with `when` in rules. -- Unlike variables in [`script`](../variables/index.md#use-cicd-variables-in-job-scripts) - sections, variables in rules expressions are always formatted as `$VARIABLE`. - -**Related topics**: - -- [Common `if` expressions for `rules`](../jobs/job_control.md#common-if-clauses-for-rules). -- [Avoid duplicate pipelines](../jobs/job_control.md#avoid-duplicate-pipelines). - -#### `rules:changes` - -Use `rules:changes` to specify when to add a job to a pipeline by checking for changes -to specific files. - -WARNING: -You should use `rules: changes` only with **branch pipelines** or **merge request pipelines**. -You can use `rules: changes` with other pipeline types, but `rules: changes` always -evaluates to true when there is no Git `push` event. Tag pipelines, scheduled pipelines, -and so on do **not** have a Git `push` event associated with them. A `rules: changes` job -is **always** added to those pipelines if there is no `if:` that limits the job to -branch or merge request pipelines. - -**Keyword type**: Job keyword. You can use it only as part of a job. - -**Possible inputs**: An array of file paths. In GitLab 13.6 and later, -[file paths can include variables](../jobs/job_control.md#variables-in-ruleschanges). - -**Example of `rules:changes`**: - -```yaml -docker build: - script: docker build -t my-image:$CI_COMMIT_REF_SLUG . - rules: - - if: '$CI_PIPELINE_SOURCE == "merge_request_event"' - changes: - - Dockerfile - when: manual - allow_failure: true -``` - -- If the pipeline is a merge request pipeline, check `Dockerfile` for changes. -- If `Dockerfile` has changed, add the job to the pipeline as a manual job, and the pipeline - continues running even if the job is not triggered (`allow_failure: true`). -- If `Dockerfile` has not changed, do not add job to any pipeline (same as `when: never`). - -**Additional details**: - -- `rules: changes` works the same way as [`only: changes` and `except: changes`](#onlychanges--exceptchanges). -- You can use `when: never` to implement a rule similar to [`except:changes`](#onlychanges--exceptchanges). - -#### `rules:exists` - -> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/24021) in GitLab 12.4. - -Use `exists` to run a job when certain files exist in the repository. - -**Keyword type**: Job keyword. You can use it only as part of a job. - -**Possible inputs**: An array of file paths. Paths are relative to the project directory (`$CI_PROJECT_DIR`) -and can't directly link outside it. File paths can use glob patterns. - -**Example of `rules:exists`**: - -```yaml -job: - script: docker build -t my-image:$CI_COMMIT_REF_SLUG . - rules: - - exists: - - Dockerfile -``` - -`job` runs if a `Dockerfile` exists anywhere in the repository. - -**Additional details**: - -- Glob patterns are interpreted with Ruby [`File.fnmatch`](https://docs.ruby-lang.org/en/2.7.0/File.html#method-c-fnmatch) - with the flags `File::FNM_PATHNAME | File::FNM_DOTMATCH | File::FNM_EXTGLOB`. -- For performance reasons, GitLab matches a maximum of 10,000 `exists` patterns or - file paths. After the 10,000th check, rules with patterned globs always match. - In other words, the `exists` rule always assumes a match in projects with more - than 10,000 files. - -#### `rules:allow_failure` - -> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/30235) in GitLab 12.8. - -Use [`allow_failure: true`](#allow_failure) in `rules:` to allow a job to fail -without stopping the pipeline. - -You can also use `allow_failure: true` with a manual job. The pipeline continues -running without waiting for the result of the manual job. `allow_failure: false` -combined with `when: manual` in rules causes the pipeline to wait for the manual -job to run before continuing. - -**Keyword type**: Job keyword. You can use it only as part of a job. - -**Possible inputs**: `true` or `false`. Defaults to `false` if not defined. - -**Example of `rules:allow_failure`**: - -```yaml -job: - script: echo "Hello, Rules!" - rules: - - if: '$CI_MERGE_REQUEST_TARGET_BRANCH_NAME == $CI_DEFAULT_BRANCH' - when: manual - allow_failure: true -``` - -If the rule matches, then the job is a manual job with `allow_failure: true`. - -**Additional details**: - -- The rule-level `rules:allow_failure` overrides the job-level [`allow_failure`](#allow_failure), - and only applies when the specific rule triggers the job. - -#### `rules:variables` - -> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/209864) in GitLab 13.7. -> - [Feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/issues/289803) in GitLab 13.10. - -Use [`variables`](#variables) in `rules:` to define variables for specific conditions. - -**Keyword type**: Job-specific. You can use it only as part of a job. - -**Possible inputs**: A hash of variables in the format `VARIABLE-NAME: value`. - -**Example of `rules:variables`**: - -```yaml -job: - variables: - DEPLOY_VARIABLE: "default-deploy" - rules: - - if: $CI_COMMIT_REF_NAME == $CI_DEFAULT_BRANCH - variables: # Override DEPLOY_VARIABLE defined - DEPLOY_VARIABLE: "deploy-production" # at the job level. - - if: $CI_COMMIT_REF_NAME =~ /feature/ - variables: - IS_A_FEATURE: "true" # Define a new variable. - script: - - echo "Run script with $DEPLOY_VARIABLE as an argument" - - echo "Run another script if $IS_A_FEATURE exists" -``` - -### `only` / `except` - -NOTE: -`only` and `except` are not being actively developed. [`rules`](#rules) is the preferred -keyword to control when to add jobs to pipelines. - -You can use `only` and `except` to control when to add jobs to pipelines. - -- Use `only` to define when a job runs. -- Use `except` to define when a job **does not** run. - -Four keywords can be used with `only` and `except`: - -- [`refs`](#onlyrefs--exceptrefs) -- [`variables`](#onlyvariables--exceptvariables) -- [`changes`](#onlychanges--exceptchanges) -- [`kubernetes`](#onlykubernetes--exceptkubernetes) - -See [specify when jobs run with `only` and `except`](../jobs/job_control.md#specify-when-jobs-run-with-only-and-except) -for more details and examples. - -#### `only:refs` / `except:refs` - -Use the `only:refs` and `except:refs` keywords to control when to add jobs to a -pipeline based on branch names or pipeline types. - -**Keyword type**: Job keyword. You can use it only as part of a job. - -**Possible inputs**: An array including any number of: - -- Branch names, for example `main` or `my-feature-branch`. -- [Regular expressions](../jobs/job_control.md#only--except-regex-syntax) - that match against branch names, for example `/^feature-.*/`. -- The following keywords: - - | **Value** | **Description** | - | -------------------------|-----------------| - | `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/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). | - | `pipelines` | For [multi-project pipelines](../multi_project_pipelines.md) created by [using the API with `CI_JOB_TOKEN`](../multi_project_pipelines.md#create-multi-project-pipelines-by-using-the-api), or the [`trigger`](#trigger) keyword. | - | `pushes` | For pipelines triggered by a `git push` event, including for branches and tags. | - | `schedules` | For [scheduled pipelines](../pipelines/schedules.md). | - | `tags` | When the Git reference for a pipeline is a tag. | - | `triggers` | For pipelines created by using a [trigger token](../triggers/index.md#trigger-token). | - | `web` | For pipelines created by using **Run pipeline** button in the GitLab UI, from the project's **CI/CD > Pipelines** section. | - -**Example of `only:refs` and `except:refs`**: - -```yaml -job1: - script: echo - only: - - main - - /^issue-.*$/ - - merge_requests - -job2: - script: echo - except: - - main - - /^stable-branch.*$/ - - schedules -``` - -**Additional details:** - -- Scheduled pipelines run on specific branches, so jobs configured with `only: branches` - run on scheduled pipelines too. Add `except: schedules` to prevent jobs with `only: branches` - from running on scheduled pipelines. -- `only` or `except` used without any other keywords are equivalent to `only: refs` - or `except: refs`. For example, the following two jobs configurations have the same - behavior: - - ```yaml - job1: - script: echo - only: - - branches - - job2: - script: echo - only: - refs: - - branches - ``` - -- If a job does not use `only`, `except`, or [`rules`](#rules), then `only` is set to `branches` - and `tags` by default. - - For example, `job1` and `job2` are equivalent: - - ```yaml - job1: - script: echo 'test' - - job2: - script: echo 'test' - only: - - branches - - tags - ``` - -#### `only:variables` / `except:variables` - -Use the `only:variables` or `except:variables` keywords to control when to add jobs -to a pipeline, based on the status of [CI/CD variables](../variables/index.md). - -**Keyword type**: Job keyword. You can use it only as part of a job. - -**Possible inputs**: An array of [CI/CD variable expressions](../jobs/job_control.md#cicd-variable-expressions). - -**Example of `only:variables`**: - -```yaml -deploy: - script: cap staging deploy - only: - variables: - - $RELEASE == "staging" - - $STAGING -``` - -**Related topics**: - -- [`only:variables` and `except:variables` examples](../jobs/job_control.md#only-variables--except-variables-examples). - -#### `only:changes` / `except:changes` - -> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/19232) in GitLab 11.4. - -Use the `changes` keyword with `only` to run a job, or with `except` to skip a job, -when a Git push event modifies a file. - -Use `changes` in pipelines with the following refs: - -- `branches` -- `external_pull_requests` -- `merge_requests` (see additional details about [using `only:changes` with pipelines for merge requests](../jobs/job_control.md#use-onlychanges-with-pipelines-for-merge-requests)) - -**Keyword type**: Job keyword. You can use it only as part of a job. - -**Possible inputs**: An array including any number of: - -- Paths to files. -- Wildcard paths for single directories, for example `path/to/directory/*`, or a directory - and all its subdirectories, for example `path/to/directory/**/*`. -- Wildcard ([glob](https://en.wikipedia.org/wiki/Glob_(programming))) paths for all - files with the same extension or multiple extensions, for example `*.md` or `path/to/directory/*.{rb,py,sh}`. -- Wildcard paths to files in the root directory, or all directories, wrapped in double quotes. - For example `"*.json"` or `"**/*.json"`. - -**Example of `only:changes`**: - -```yaml -docker build: - script: docker build -t my-image:$CI_COMMIT_REF_SLUG . - only: - refs: - - branches - changes: - - Dockerfile - - docker/scripts/* - - dockerfiles/**/* - - more_scripts/*.{rb,py,sh} -``` - -**Additional details**: - -- If you use refs other than `branches`, `external_pull_requests`, or `merge_requests`, - `changes` can't determine if a given file is new or old and always returns `true`. -- If you use `only: changes` with other refs, jobs ignore the changes and always run. -- If you use `except: changes` with other refs, jobs ignore the changes and never run. - -**Related topics**: - -- [`only: changes` and `except: changes` examples](../jobs/job_control.md#onlychanges--exceptchanges-examples). -- If you use `changes` with [only allow merge requests to be merged if the pipeline succeeds](../../user/project/merge_requests/merge_when_pipeline_succeeds.md#only-allow-merge-requests-to-be-merged-if-the-pipeline-succeeds), - you should [also use `only:merge_requests`](../jobs/job_control.md#use-onlychanges-with-pipelines-for-merge-requests). -- Use `changes` with [new branches or tags *without* pipelines for merge requests](../jobs/job_control.md#use-onlychanges-without-pipelines-for-merge-requests). -- Use `changes` with [scheduled pipelines](../jobs/job_control.md#use-onlychanges-with-scheduled-pipelines). - -#### `only:kubernetes` / `except:kubernetes` - -Use `only:kubernetes` or `except:kubernetes` to control if jobs are added to the pipeline -when the Kubernetes service is active in the project. - -**Keyword type**: Job-specific. You can use it only as part of a job. - -**Possible inputs**: The `kubernetes` strategy accepts only the `active` keyword. - -**Example of `only:kubernetes`**: - -```yaml -deploy: - only: - kubernetes: active -``` - -In this example, the `deploy` job runs only when the Kubernetes service is active -in the project. - -### `needs` - -> - [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/47063) in GitLab 12.2. -> - In GitLab 12.3, maximum number of jobs in `needs` array raised from five to 50. -> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/30631) in GitLab 12.8, `needs: []` lets jobs start immediately. - -Use `needs:` to execute jobs out-of-order. Relationships between jobs -that use `needs` can be visualized as a [directed acyclic graph](../directed_acyclic_graph/index.md). - -You can ignore stage ordering and run some jobs without waiting for others to complete. -Jobs in multiple stages can run concurrently. - -The following example creates four paths of execution: - -- Linter: the `lint` job runs immediately without waiting for the `build` stage - to complete because it has no needs (`needs: []`). -- Linux path: the `linux:rspec` and `linux:rubocop` jobs runs as soon as the `linux:build` - job finishes without waiting for `mac:build` to finish. -- macOS path: the `mac:rspec` and `mac:rubocop` jobs runs as soon as the `mac:build` - job finishes, without waiting for `linux:build` to finish. -- The `production` job runs as soon as all previous jobs finish; in this case: - `linux:build`, `linux:rspec`, `linux:rubocop`, `mac:build`, `mac:rspec`, `mac:rubocop`. - -```yaml -linux:build: - stage: build - script: echo "Building linux..." - -mac:build: - stage: build - script: echo "Building mac..." - -lint: - stage: test - needs: [] - script: echo "Linting..." - -linux:rspec: - stage: test - needs: ["linux:build"] - script: echo "Running rspec on linux..." - -linux:rubocop: - stage: test - needs: ["linux:build"] - script: echo "Running rubocop on linux..." - -mac:rspec: - stage: test - needs: ["mac:build"] - script: echo "Running rspec on mac..." - -mac:rubocop: - stage: test - needs: ["mac:build"] - script: echo "Running rubocop on mac..." - -production: - stage: deploy - script: echo "Running production..." -``` - -#### Requirements and limitations - -- In GitLab 13.9 and older, if `needs:` refers to a job that might not be added to - a pipeline because of `only`, `except`, or `rules`, the pipeline might fail to create. -- The maximum number of jobs that a single job can need in the `needs:` array is limited: - - For GitLab.com, the limit is 50. For more information, see our - [infrastructure issue](https://gitlab.com/gitlab-com/gl-infra/infrastructure/-/issues/7541). - - For self-managed instances, the limit is: 50. This limit [can be changed](#changing-the-needs-job-limit). -- If `needs:` refers to a job that uses the [`parallel`](#parallel) keyword, - it depends on all jobs created in parallel, not just one job. It also downloads - artifacts from all the parallel jobs by default. If the artifacts have the same - name, they overwrite each other and only the last one downloaded is saved. -- `needs:` is similar to `dependencies:` in that it must use jobs from prior stages, - meaning it's impossible to create circular dependencies. Depending on jobs in the - current stage is not possible either, but support [is planned](https://gitlab.com/gitlab-org/gitlab/-/issues/30632). -- Stages must be explicitly defined for all jobs - that have the keyword `needs:` or are referred to by one. - -##### Changing the `needs:` job limit **(FREE SELF)** - -The maximum number of jobs that can be defined in `needs:` defaults to 50. - -A GitLab administrator with [access to the GitLab Rails console](../../administration/feature_flags.md) -can choose a custom limit. For example, to set the limit to 100: - -```ruby -Plan.default.actual_limits.update!(ci_needs_size_limit: 100) -``` - -To disable directed acyclic graphs (DAG), set the limit to `0`. - -#### Artifact downloads with `needs` - -> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/14311) in GitLab v12.6. - -When a job uses `needs`, it no longer downloads all artifacts from previous stages -by default, because jobs with `needs` can start before earlier stages complete. With -`needs` you can only download artifacts from the jobs listed in the `needs:` configuration. - -Use `artifacts: true` (default) or `artifacts: false` to control when artifacts are -downloaded in jobs that use `needs`. - -In the following example, the `rspec` job downloads the `build_job` artifacts, but the -`rubocop` job does not: - -```yaml -build_job: - stage: build - artifacts: - paths: - - binaries/ - -rspec: - stage: test - needs: - - job: build_job - artifacts: true - -rubocop: - stage: test - needs: - - job: build_job - artifacts: false -``` - -In the following example, the `rspec` job downloads the artifacts from all three `build_jobs`. -`artifacts` is: - -- Set to true for `build_job_1`. -- Defaults to true for both `build_job_2` and `build_job_3`. - -```yaml -rspec: - needs: - - job: build_job_1 - artifacts: true - - job: build_job_2 - - build_job_3 -``` - -In GitLab 12.6 and later, you can't combine the [`dependencies`](#dependencies) keyword -with `needs`. - -#### Cross project artifact downloads with `needs` **(PREMIUM)** - -> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/14311) in GitLab v12.7. - -Use `needs` to download artifacts from up to five jobs in pipelines: - -- [On other refs in the same project](#artifact-downloads-between-pipelines-in-the-same-project). -- In different projects, groups and namespaces. - -```yaml -build_job: - stage: build - script: - - ls -lhR - needs: - - project: namespace/group/project-name - job: build-1 - ref: main - artifacts: true -``` - -`build_job` downloads the artifacts from the latest successful `build-1` job -on the `main` branch in the `group/project-name` project. If the project is in the -same group or namespace, you can omit them from the `project:` keyword. For example, -`project: group/project-name` or `project: project-name`. - -The user running the pipeline must have at least `reporter` access to the group or project, or the group/project must have public visibility. - -##### Artifact downloads between pipelines in the same project - -Use `needs` to download artifacts from different pipelines in the current project. -Set the `project` keyword as the current project's name, and specify a ref. - -In the following example, `build_job` downloads the artifacts for the latest successful -`build-1` job with the `other-ref` ref: - -```yaml -build_job: - stage: build - script: - - ls -lhR - needs: - - project: group/same-project-name - job: build-1 - ref: other-ref - artifacts: true -``` - -CI/CD variable support for `project:`, `job:`, and `ref` was [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/202093) -in GitLab 13.3. [Feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/issues/235761) in GitLab 13.4. - -For example: - -```yaml -build_job: - stage: build - script: - - ls -lhR - needs: - - project: $CI_PROJECT_PATH - job: $DEPENDENCY_JOB_NAME - ref: $ARTIFACTS_DOWNLOAD_REF - artifacts: true -``` - -You can't download artifacts from jobs that run in [`parallel:`](#parallel). - -To download artifacts between [parent-child pipelines](../parent_child_pipelines.md), -use [`needs:pipeline`](#artifact-downloads-to-child-pipelines). - -You should not download artifacts from the same ref as a running pipeline. Concurrent -pipelines running on the same ref could override the artifacts. - -##### Artifact downloads to child pipelines - -> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/255983) in GitLab v13.7. - -A [child pipeline](../parent_child_pipelines.md) can download artifacts from a job in -its parent pipeline or another child pipeline in the same parent-child pipeline hierarchy. - -For example, with the following parent pipeline that has a job that creates some artifacts: - -```yaml -create-artifact: - stage: build - script: echo 'sample artifact' > artifact.txt - artifacts: - paths: [artifact.txt] - -child-pipeline: - stage: test - trigger: - include: child.yml - strategy: depend - variables: - PARENT_PIPELINE_ID: $CI_PIPELINE_ID -``` - -A job in the child pipeline can download artifacts from the `create-artifact` job in -the parent pipeline: - -```yaml -use-artifact: - script: cat artifact.txt - needs: - - pipeline: $PARENT_PIPELINE_ID - job: create-artifact -``` - -The `pipeline` attribute accepts a pipeline ID and it must be a pipeline present -in the same parent-child pipeline hierarchy of the given pipeline. - -The `pipeline` attribute does not accept the current pipeline ID (`$CI_PIPELINE_ID`). -To download artifacts from a job in the current pipeline, use the basic form of [`needs`](#artifact-downloads-with-needs). - -#### Optional `needs` - -> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/30680) in GitLab 13.10. -> - [Feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/issues/323891) in GitLab 14.0. - -To need a job that sometimes does not exist in the pipeline, add `optional: true` -to the `needs` configuration. If not defined, `optional: false` is the default. - -Jobs that use [`rules`](#rules), [`only`, or `except`](#only--except), might -not always exist in a pipeline. When the pipeline starts, it checks the `needs` -relationships before running. Without `optional: true`, needs relationships that -point to a job that does not exist stops the pipeline from starting and causes a pipeline -error similar to: - -- `'job1' job needs 'job2' job, but it was not added to the pipeline` - -In this example: - -- When the branch is the default branch, the `build` job exists in the pipeline, and the `rspec` - job waits for it to complete before starting. -- When the branch is not the default branch, the `build` job does not exist in the pipeline. - The `rspec` job runs immediately (similar to `needs: []`) because its `needs` - relationship to the `build` job is optional. - -```yaml -build: - stage: build - rules: - - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH - -rspec: - stage: test - needs: - - job: build - optional: true -``` - -### `tags` - -Use `tags` to select a specific runner from the list of all runners that are -available for the project. - -When you register a runner, you can specify the runner's tags, for -example `ruby`, `postgres`, `development`. - -In the following example, the job is run by a runner that -has both `ruby` and `postgres` tags defined. - -```yaml -job: - tags: - - ruby - - postgres -``` - -You can use tags to run different jobs on different platforms. For -example, if you have an OS X runner with tag `osx` and a Windows runner with tag -`windows`, you can run a job on each platform: - -```yaml -windows job: - stage: - - build - tags: - - windows - script: - - echo Hello, %USERNAME%! - -osx job: - stage: - - build - tags: - - osx - script: - - echo "Hello, $USER!" -``` - -### `allow_failure` - -Use `allow_failure` when you want to let a job fail without impacting the rest of the CI -suite. The default value is `false`, except for [manual](#whenmanual) jobs that use -the `when: manual` syntax. - -In jobs that use [`rules:`](#rules), all jobs default to `allow_failure: false`, -*including* `when: manual` jobs. - -When `allow_failure` is set to `true` and the job fails, the job shows an orange warning in the UI. -However, the logical flow of the pipeline considers the job a -success/passed, and is not blocked. - -Assuming all other jobs are successful, the job's stage and its pipeline -show the same orange warning. However, the associated commit is marked as -"passed", without warnings. - -In the following example, `job1` and `job2` run in parallel. If `job1` -fails, it doesn't stop the next stage from running, because it's marked with -`allow_failure: true`: - -```yaml -job1: - stage: test - script: - - execute_script_that_will_fail - allow_failure: true - -job2: - stage: test - script: - - execute_script_that_will_succeed - -job3: - stage: deploy - script: - - deploy_to_staging -``` - -#### `allow_failure:exit_codes` - -> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/273157) in GitLab 13.8. -> - [Feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/issues/292024) in GitLab 13.9. - -Use `allow_failure:exit_codes` to dynamically control if a job should be allowed -to fail. You can list which exit codes are not considered failures. The job fails -for any other exit code: - -```yaml -test_job_1: - script: - - echo "Run a script that results in exit code 1. This job fails." - - exit 1 - allow_failure: - exit_codes: 137 - -test_job_2: - script: - - echo "Run a script that results in exit code 137. This job is allowed to fail." - - exit 137 - allow_failure: - exit_codes: - - 137 - - 255 -``` - -### `when` - -Use `when` to implement jobs that run in case of failure or despite the -failure. - -The valid values of `when` are: - -1. `on_success` (default) - Execute job only when all jobs in earlier stages succeed, - or are considered successful because they have `allow_failure: true`. -1. `on_failure` - Execute job only when at least one job in an earlier stage fails. -1. `always` - Execute job regardless of the status of jobs in earlier stages. -1. `manual` - Execute job [manually](#whenmanual). -1. `delayed` - [Delay the execution of a job](#whendelayed) for a specified duration. - Added in GitLab 11.14. -1. `never`: - - With job [`rules`](#rules), don't execute job. - - With [`workflow:rules`](#workflow), don't run pipeline. - -In the following example, the script: - -1. Executes `cleanup_build_job` only when `build_job` fails. -1. Always executes `cleanup_job` as the last step in pipeline regardless of - success or failure. -1. Executes `deploy_job` when you run it manually in the GitLab UI. - -```yaml -stages: - - build - - cleanup_build - - test - - deploy - - cleanup - -build_job: - stage: build - script: - - make build - -cleanup_build_job: - stage: cleanup_build - script: - - cleanup build when failed - when: on_failure - -test_job: - stage: test - script: - - make test - -deploy_job: - stage: deploy - script: - - make deploy - when: manual - -cleanup_job: - stage: cleanup - script: - - cleanup after jobs - when: always -``` - -#### `when:manual` - -A manual job is a type of job that is not executed automatically and must be explicitly -started by a user. You might want to use manual jobs for things like deploying to production. - -To make a job manual, add `when: manual` to its configuration. - -When the pipeline starts, manual jobs display as skipped and do not run automatically. -They can be started from the pipeline, job, [environment](../environments/index.md#configure-manual-deployments), -and deployment views. - -Manual jobs can be either optional or blocking: - -- **Optional**: Manual jobs have [`allow_failure: true](#allow_failure) set by default - and are considered optional. The status of an optional manual job does not contribute - to the overall pipeline status. A pipeline can succeed even if all its manual jobs fail. - -- **Blocking**: To make a blocking manual job, add `allow_failure: false` to its configuration. - Blocking manual jobs stop further execution of the pipeline at the stage where the - job is defined. To let the pipeline continue running, click **{play}** (play) on - the blocking manual job. - - Merge requests in projects with [merge when pipeline succeeds](../../user/project/merge_requests/merge_when_pipeline_succeeds.md) - enabled can't be merged with a blocked pipeline. Blocked pipelines show a status - of **blocked**. - -When you use [`rules:`](#rules), `allow_failure` defaults to `false`, including for manual jobs. - -To trigger a manual job, a user must have permission to merge to the assigned branch. -You can use [protected branches](../../user/project/protected_branches.md) to more strictly -[protect manual deployments](#protecting-manual-jobs) from being run by unauthorized users. - -In [GitLab 13.5](https://gitlab.com/gitlab-org/gitlab/-/issues/201938) and later, you -can use `when:manual` in the same job as [`trigger`](#trigger). In GitLab 13.4 and -earlier, using them together causes the error `jobs:#{job-name} when should be on_success, on_failure or always`. - -##### Protecting manual jobs **(PREMIUM)** - -Use [protected environments](../environments/protected_environments.md) -to define a list of users authorized to run a manual job. You can authorize only -the users associated with a protected environment to trigger manual jobs, which can: - -- More precisely limit who can deploy to an environment. -- Block a pipeline until an approved user "approves" it. - -To protect a manual job: - -1. Add an `environment` to the job. For example: - - ```yaml - deploy_prod: - stage: deploy - script: - - echo "Deploy to production server" - environment: - name: production - url: https://example.com - when: manual - rules: - - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH - ``` - -1. In the [protected environments settings](../environments/protected_environments.md#protecting-environments), - select the environment (`production` in this example) and add the users, roles or groups - that are authorized to trigger the manual job to the **Allowed to Deploy** list. Only those in - this list can trigger this manual job, as well as GitLab administrators - who are always able to use protected environments. - -You can use protected environments with blocking manual jobs to have a list of users -allowed to approve later pipeline stages. Add `allow_failure: false` to the protected -manual job and the pipeline's next stages only run after the manual job is triggered -by authorized users. - -#### `when:delayed` - -> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/51352) in GitLab 11.4. - -Use `when: delayed` to execute scripts after a waiting period, or if you want to avoid -jobs immediately entering the `pending` state. - -You can set the period with `start_in` keyword. The value of `start_in` is an elapsed time in seconds, unless a unit is -provided. `start_in` must be less than or equal to one week. Examples of valid values include: - -- `'5'` -- `5 seconds` -- `30 minutes` -- `1 day` -- `1 week` - -When a stage includes a delayed job, the pipeline doesn't progress until the delayed job finishes. -You can use this keyword to insert delays between different stages. - -The timer of a delayed job starts immediately after the previous stage completes. -Similar to other types of jobs, a delayed job's timer doesn't start unless the previous stage passes. - -The following example creates a job named `timed rollout 10%` that is executed 30 minutes after the previous stage completes: - -```yaml -timed rollout 10%: - stage: deploy - script: echo 'Rolling out 10% ...' - when: delayed - start_in: 30 minutes -``` - -To stop the active timer of a delayed job, click the **{time-out}** (**Unschedule**) button. -This job can no longer be scheduled to run automatically. You can, however, execute the job manually. - -To start a delayed job immediately, click the **Play** button. -Soon GitLab Runner picks up and starts the job. - -### `environment` - -Use `environment` to define the [environment](../environments/index.md) that a job deploys to. -For example: - -```yaml -deploy to production: - stage: deploy - script: git push production HEAD:main - environment: production -``` - -You can assign a value to the `environment` keyword by using: - -- Plain text, like `production`. -- Variables, including CI/CD variables, predefined, secure, or variables - defined in the `.gitlab-ci.yml` file. - -You can't use variables defined in a `script` section. - -If you specify an `environment` and no environment with that name exists, -an environment is created. - -#### `environment:name` - -Set a name for an [environment](../environments/index.md). For example: - -```yaml -deploy to production: - stage: deploy - script: git push production HEAD:main - environment: - name: production -``` - -Common environment names are `qa`, `staging`, and `production`, but you can use any -name you want. - -You can assign a value to the `name` keyword by using: - -- Plain text, like `staging`. -- Variables, including CI/CD variables, predefined, secure, or variables - defined in the `.gitlab-ci.yml` file. - -You can't use variables defined in a `script` section. - -The environment `name` can contain: - -- Letters -- Digits -- Spaces -- `-` -- `_` -- `/` -- `$` -- `{` -- `}` - -#### `environment:url` - -Set a URL for an [environment](../environments/index.md). For example: - -```yaml -deploy to production: - stage: deploy - script: git push production HEAD:main - environment: - name: production - url: https://prod.example.com -``` - -After the job completes, you can access the URL by using a button in the merge request, -environment, or deployment pages. - -You can assign a value to the `url` keyword by using: - -- Plain text, like `https://prod.example.com`. -- Variables, including CI/CD variables, predefined, secure, or variables - defined in the `.gitlab-ci.yml` file. - -You can't use variables defined in a `script` section. - -#### `environment:on_stop` - -Closing (stopping) environments can be achieved with the `on_stop` keyword -defined under `environment`. It declares a different job that runs to close the -environment. - -Read the `environment:action` section for an example. - -#### `environment:action` - -Use the `action` keyword to specify jobs that prepare, start, or stop environments. - -| **Value** | **Description** | -|-----------|---------------------------------------------------------------------------------------------------------------------------------------------------------------| -| `start` | Default value. Indicates that job starts the environment. The deployment is created after the job starts. | -| `prepare` | Indicates that the job is only preparing the environment. It does not trigger deployments. [Read more about preparing environments](../environments/index.md#prepare-an-environment-without-creating-a-deployment). | -| `stop` | Indicates that job stops deployment. See the example below. | - -Take for instance: - -```yaml -review_app: - stage: deploy - script: make deploy-app - environment: - name: review/$CI_COMMIT_REF_NAME - url: https://$CI_ENVIRONMENT_SLUG.example.com - on_stop: stop_review_app - -stop_review_app: - stage: deploy - variables: - GIT_STRATEGY: none - script: make delete-app - when: manual - environment: - name: review/$CI_COMMIT_REF_NAME - action: stop -``` - -In the above example, the `review_app` job deploys to the `review` -environment. A new `stop_review_app` job is listed under `on_stop`. -After the `review_app` job is finished, it triggers the -`stop_review_app` job based on what is defined under `when`. In this case, -it is set to `manual`, so it needs a [manual action](#whenmanual) from -the GitLab UI to run. - -Also in the example, `GIT_STRATEGY` is set to `none`. If the -`stop_review_app` job is [automatically triggered](../environments/index.md#stopping-an-environment), -the runner won't try to check out the code after the branch is deleted. - -The example also overwrites global variables. If your `stop` `environment` job depends -on global variables, use [anchor variables](#yaml-anchors-for-variables) when you set the `GIT_STRATEGY` -to change the job without overriding the global variables. - -The `stop_review_app` job is **required** to have the following keywords defined: - -- `when`, defined at either: - - [The job level](#when). - - [In a rules clause](#rules). If you use `rules:` and `when: manual`, you should - also set [`allow_failure: true`](#allow_failure) so the pipeline can complete - even if the job doesn't run. -- `environment:name` -- `environment:action` - -Additionally, both jobs should have matching [`rules`](#only--except) -or [`only/except`](#only--except) configuration. - -In the examples above, if the configuration is not identical: - -- The `stop_review_app` job might not be included in all pipelines that include the `review_app` job. -- It is not possible to trigger the `action: stop` to stop the environment automatically. - -#### `environment:auto_stop_in` - -> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/20956) in GitLab 12.8. - -The `auto_stop_in` keyword is for specifying the lifetime of the environment, -that when expired, GitLab automatically stops them. - -For example, - -```yaml -review_app: - script: deploy-review-app - environment: - name: review/$CI_COMMIT_REF_NAME - auto_stop_in: 1 day -``` - -When the environment for `review_app` is created, the environment's lifetime is set to `1 day`. -Every time the review app is deployed, that lifetime is also reset to `1 day`. - -For more information, see -[the environments auto-stop documentation](../environments/index.md#stop-an-environment-after-a-certain-time-period) - -#### `environment:kubernetes` - -> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/27630) in GitLab 12.6. - -Use the `kubernetes` keyword to configure deployments to a -[Kubernetes cluster](../../user/project/clusters/index.md) that is associated with your project. - -For example: - -```yaml -deploy: - stage: deploy - script: make deploy-app - environment: - name: production - kubernetes: - namespace: production -``` - -This configuration sets up the `deploy` job to deploy to the `production` -environment, using the `production` -[Kubernetes namespace](https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/). - -For more information, see -[Available settings for `kubernetes`](../environments/index.md#configure-kubernetes-deployments). - -NOTE: -Kubernetes configuration is not supported for Kubernetes clusters -that are [managed by GitLab](../../user/project/clusters/index.md#gitlab-managed-clusters). -To follow progress on support for GitLab-managed clusters, see the -[relevant issue](https://gitlab.com/gitlab-org/gitlab/-/issues/38054). - -#### `environment:deployment_tier` - -> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/300741) in GitLab 13.10. - -Use the `deployment_tier` keyword to specify the tier of the deployment environment: - -```yaml -deploy: - script: echo - environment: - name: customer-portal - deployment_tier: production -``` - -For more information, -see [Deployment tier of environments](../environments/index.md#deployment-tier-of-environments). - -#### Dynamic environments - -Use CI/CD [variables](../variables/index.md) to dynamically name environments. - -For example: - -```yaml -deploy as review app: - stage: deploy - script: make deploy - environment: - name: review/$CI_COMMIT_REF_NAME - url: https://$CI_ENVIRONMENT_SLUG.example.com/ -``` - -The `deploy as review app` job is marked as a deployment to dynamically -create the `review/$CI_COMMIT_REF_NAME` environment. `$CI_COMMIT_REF_NAME` -is a [CI/CD variable](../variables/index.md) set by the runner. The -`$CI_ENVIRONMENT_SLUG` variable is based on the environment name, but suitable -for inclusion in URLs. If the `deploy as review app` job runs in a branch named -`pow`, this environment would be accessible with a URL like `https://review-pow.example.com/`. - -The common use case is to create dynamic environments for branches and use them -as Review Apps. You can see an example that uses Review Apps at -. - -### `cache` - -Use `cache` to specify a list of files and directories to -cache between jobs. You can only use paths that are in the local working copy. - -Caching is shared between pipelines and jobs. Caches are restored before [artifacts](#artifacts). - -Learn more about caches in [Caching in GitLab CI/CD](../caching/index.md). - -#### `cache:paths` - -Use the `cache:paths` keyword to choose which files or directories to cache. - -**Keyword type**: Job-specific. You can use it only as part of a job. - -**Possible inputs**: An array of paths relative to the project directory (`$CI_PROJECT_DIR`). -You can use wildcards that use [glob](https://en.wikipedia.org/wiki/Glob_(programming)) -patterns: - -- In [GitLab Runner 13.0](https://gitlab.com/gitlab-org/gitlab-runner/-/issues/2620) and later, -[`doublestar.Glob`](https://pkg.go.dev/github.com/bmatcuk/doublestar@v1.2.2?tab=doc#Match). -- In GitLab Runner 12.10 and earlier, -[`filepath.Match`](https://pkg.go.dev/path/filepath#Match). - -**Example of `cache:paths`**: - -Cache all files in `binaries` that end in `.apk` and the `.config` file: - -```yaml -rspec: - script: - - echo "This job uses a cache." - cache: - key: binaries-cache - paths: - - binaries/*.apk - - .config -``` - -**Related topics**: - -- See the [common `cache` use cases](../caching/index.md#common-use-cases-for-caches) for more - `cache:paths` examples. - -#### `cache:key` - -Use the `cache:key` keyword to give each cache a unique identifying key. All jobs -that use the same cache key use the same cache, including in different pipelines. - -If not set, the default key is `default`. All jobs with the `cache:` keyword but -no `cache:key` share the `default` cache. - -**Keyword type**: Job-specific. You can use it only as part of a job. - -**Possible inputs**: - -- A string. -- A [predefined variables](../variables/index.md). -- A combination of both. - -**Example of `cache:key`**: - -```yaml -cache-job: - script: - - echo "This job uses a cache." - cache: - key: binaries-cache-$CI_COMMIT_REF_SLUG - paths: - - binaries/ -``` - -**Additional details**: - -- If you use **Windows Batch** to run your shell scripts you need to replace - `$` with `%`. For example: `key: %CI_COMMIT_REF_SLUG%` -- The `cache:key` value can't contain: - - - The `/` character, or the equivalent URI-encoded `%2F`. - - Only the `.` character (any number), or the equivalent URI-encoded `%2E`. - -- The cache is shared between jobs, so if you're using different - paths for different jobs, you should also set a different `cache:key`. - Otherwise cache content can be overwritten. - -**Related topics**: - -- You can specify a [fallback cache key](../caching/index.md#use-a-fallback-cache-key) - to use if the specified `cache:key` is not found. -- You can [use multiple cache keys](../caching/index.md#use-multiple-caches) in a single job. -- See the [common `cache` use cases](../caching/index.md#common-use-cases-for-caches) for more - `cache:key` examples. - -##### `cache:key:files` - -> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/18986) in GitLab v12.5. - -Use the `cache:key:files` keyword to generate a new key when one or two specific files -change. `cache:key:files` lets you reuse some caches, and rebuild them less often, -which speeds up subsequent pipeline runs. - -**Keyword type**: Job-specific. You can use it only as part of a job. - -**Possible inputs**: An array of one or two file paths. - -**Example of `cache:key:files`**: - -```yaml -cache-job: - script: - - echo "This job uses a cache." - cache: - key: - files: - - Gemfile.lock - - package.json - paths: - - vendor/ruby - - node_modules -``` - -This example creates a cache for Ruby and Node.js dependencies. The cache -is tied to the current versions of the `Gemfile.lock` and `package.json` files. When one of -these files changes, a new cache key is computed and a new cache is created. Any future -job runs that use the same `Gemfile.lock` and `package.json` with `cache:key:files` -use the new cache, instead of rebuilding the dependencies. - -**Additional details**: The cache `key` is a SHA computed from the most recent commits -that changed each listed file. If neither file is changed in any commits, the -fallback key is `default`. - -##### `cache:key:prefix` - -> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/18986) in GitLab v12.5. - -Use `cache:key:prefix` to combine a prefix with the SHA computed for [`cache:key:files`](#cachekeyfiles). - -**Keyword type**: Job-specific. You can use it only as part of a job. - -**Possible inputs**: - -- A string -- A [predefined variables](../variables/index.md) -- A combination of both. - -**Example of `cache:key:prefix`**: - -```yaml -rspec: - script: - - echo "This rspec job uses a cache." - cache: - key: - files: - - Gemfile.lock - prefix: $CI_JOB_NAME - paths: - - vendor/ruby -``` - -For example, adding a `prefix` of `$CI_JOB_NAME` causes the key to look like `rspec-feef9576d21ee9b6a32e30c5c79d0a0ceb68d1e5`. -If a branch changes `Gemfile.lock`, that branch has a new SHA checksum for `cache:key:files`. -A new cache key is generated, and a new cache is created for that key. If `Gemfile.lock` -is not found, the prefix is added to `default`, so the key in the example would be `rspec-default`. - -**Additional details**: If no file in `cache:key:files` is changed in any commits, -the prefix is added to the `default` key. - -#### `cache:untracked` - -Use `untracked: true` to cache all files that are untracked in your Git repository: - -**Keyword type**: Job-specific. You can use it only as part of a job. - -**Possible inputs**: `true` or `false` (default). - -**Example of `cache:untracked`**: - -```yaml -rspec: - script: test - cache: - untracked: true -``` - -**Additional details**: - -- You can combine `cache:untracked` with `cache:paths` to cache all untracked files - as well as files in the configured paths. For example: - - ```yaml - rspec: - script: test - cache: - untracked: true - paths: - - binaries/ - ``` - -#### `cache:when` - -> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/18969) in GitLab 13.5 and GitLab Runner v13.5.0. - -Use `cache:when` to define when to save the cache, based on the status of the job. - -**Keyword type**: Job-specific. You can use it only as part of a job. - -**Possible inputs**: - -- `on_success` (default): Save the cache only when the job succeeds. -- `on_failure`: Save the cache only when the job fails. -- `always`: Always save the cache. - -**Example of `cache:untracked`**: - -```yaml -rspec: - script: rspec - cache: - paths: - - rspec/ - when: 'always' -``` - -This example stores the cache whether or not the job fails or succeeds. - -#### `cache:policy` - -To change the upload and download behavior of a cache, use the `cache:policy` keyword. -By default, the job downloads the cache when the job starts, and uploads changes -to the cache when the job ends. This is the `pull-push` policy (default). - -To set a job to only download the cache when the job starts, but never upload changes -when the job finishes, use `cache:policy:pull`. - -To set a job to only upload a cache when the job finishes, but never download the -cache when the job starts, use `cache:policy:push`. - -Use the `pull` policy when you have many jobs executing in parallel that use the same cache. -This policy speeds up job execution and reduces load on the cache server. You can -use a job with the `push` policy to build the cache. - -**Keyword type**: Job-specific. You can use it only as part of a job. - -**Possible inputs**: - -- `pull` -- `push` -- `pull-push` (default) - -**Example of `cache:policy`**: - -```yaml -prepare-dependencies-job: - stage: build - cache: - key: gems - paths: - - vendor/bundle - policy: push - script: - - echo "This job only downloads dependencies and builds the cache." - - echo "Downloading dependencies..." - -faster-test-job: - stage: test - cache: - key: gems - paths: - - vendor/bundle - policy: pull - script: - - echo "This job script uses the cache, but does not update it." - - echo "Running tests..." -``` - -### `artifacts` - -Use `artifacts` to specify a list of files and directories that are -attached to the job when it [succeeds, fails, or always](#artifactswhen). - -The artifacts are sent to GitLab after the job finishes. They are -available for download in the GitLab UI if the size is not -larger than the [maximum artifact size](../../user/gitlab_com/index.md#gitlab-cicd). - -By default, jobs in later stages automatically download all the artifacts created -by jobs in earlier stages. You can control artifact download behavior in jobs with -[`dependencies`](#dependencies). - -When using the [`needs`](#artifact-downloads-with-needs) keyword, jobs can only download -artifacts from the jobs defined in the `needs` configuration. - -Job artifacts are only collected for successful jobs by default, and -artifacts are restored after [caches](#cache). - -[Read more about artifacts](../pipelines/job_artifacts.md). - -#### `dependencies` - -By default, all `artifacts` from previous stages -are passed to each job. However, you can use the `dependencies` keyword to -define a limited list of jobs to fetch artifacts from. You can also set a job to download no artifacts at all. - -To use this feature, define `dependencies` in context of the job and pass -a list of all previous jobs the artifacts should be downloaded from. - -You can define jobs from stages that were executed before the current one. -An error occurs if you define jobs from the current or an upcoming stage. - -To prevent a job from downloading artifacts, define an empty array. - -When you use `dependencies`, the status of the previous job is not considered. -If a job fails or it's a manual job that isn't triggered, no error occurs. - -The following example defines two jobs with artifacts: `build:osx` and -`build:linux`. When the `test:osx` is executed, the artifacts from `build:osx` -are downloaded and extracted in the context of the build. The same happens -for `test:linux` and artifacts from `build:linux`. - -The job `deploy` downloads artifacts from all previous jobs because of -the [stage](#stages) precedence: - -```yaml -build:osx: - stage: build - script: make build:osx - artifacts: - paths: - - binaries/ - -build:linux: - stage: build - script: make build:linux - artifacts: - paths: - - binaries/ - -test:osx: - stage: test - script: make test:osx - dependencies: - - build:osx - -test:linux: - stage: test - script: make test:linux - dependencies: - - build:linux - -deploy: - stage: deploy - script: make deploy -``` - -##### When a dependent job fails - -> Introduced in GitLab 10.3. - -If the artifacts of the job that is set as a dependency are -[expired](#artifactsexpire_in) or -[deleted](../pipelines/job_artifacts.md#delete-job-artifacts), then -the dependent job fails. - -#### `artifacts:exclude` - -> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/15122) in GitLab 13.1 -> - Requires GitLab Runner 13.1 - -`exclude` makes it possible to prevent files from being added to an artifacts -archive. - -Similar to [`artifacts:paths`](#artifactspaths), `exclude` paths are relative -to the project directory. You can use Wildcards that use -[glob](https://en.wikipedia.org/wiki/Glob_(programming)) or -[`doublestar.PathMatch`](https://pkg.go.dev/github.com/bmatcuk/doublestar@v1.2.2?tab=doc#PathMatch) patterns. - -For example, to store all files in `binaries/`, but not `*.o` files located in -subdirectories of `binaries/`: - -```yaml -artifacts: - paths: - - binaries/ - exclude: - - binaries/**/*.o -``` - -Unlike [`artifacts:paths`](#artifactspaths), `exclude` paths are not recursive. To exclude all of the contents of a directory, you can match them explicitly rather than matching the directory itself. - -For example, to store all files in `binaries/` but nothing located in the `temp/` subdirectory: - -```yaml -artifacts: - paths: - - binaries/ - exclude: - - binaries/temp/**/* -``` - -Files matched by [`artifacts:untracked`](#artifactsuntracked) can be excluded using -`artifacts:exclude` too. - -#### `artifacts:expire_in` - -> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/16267) in GitLab 13.0 behind a disabled feature flag, the latest job artifacts are kept regardless of expiry time. -> - [Made default behavior](https://gitlab.com/gitlab-org/gitlab/-/issues/229936) in GitLab 13.4. -> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/241026) in GitLab 13.8, keeping latest job artifacts can be disabled at the project level. -> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/276583) in GitLab 13.9, keeping latest job artifacts can be disabled instance-wide. -> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/321323) in GitLab 13.12, the latest pipeline artifacts are kept regardless of expiry time. - -Use `expire_in` to specify how long [job artifacts](../pipelines/job_artifacts.md) are stored before -they expire and are deleted. The `expire_in` setting does not affect: - -- Artifacts from the latest job, unless this keeping the latest job artifacts is: - - [Disabled at the project level](../pipelines/job_artifacts.md#keep-artifacts-from-most-recent-successful-jobs). - - [Disabled instance-wide](../../user/admin_area/settings/continuous_integration.md#keep-the-latest-artifacts-for-all-jobs-in-the-latest-successful-pipelines). -- [Pipeline artifacts](../pipelines/pipeline_artifacts.md). It's not possible to specify an - expiration date for these: - - Pipeline artifacts from the latest pipeline are kept forever. - - Other pipeline artifacts are erased after one week. - -The value of `expire_in` is an elapsed time in seconds, unless a unit is provided. Valid values -include: - -- `'42'` -- `42 seconds` -- `3 mins 4 sec` -- `2 hrs 20 min` -- `2h20min` -- `6 mos 1 day` -- `47 yrs 6 mos and 4d` -- `3 weeks and 2 days` -- `never` - -To expire artifacts one week after being uploaded: - -```yaml -job: - artifacts: - expire_in: 1 week -``` - -The expiration time period begins when the artifact is uploaded and stored on GitLab. If the expiry -time is not defined, it defaults to the -[instance wide setting](../../user/admin_area/settings/continuous_integration.md#default-artifacts-expiration) -(30 days by default). - -To override the expiration date and protect artifacts from being automatically deleted: - -- Use the **Keep** button on the job page. -- [In GitLab 13.3 and later](https://gitlab.com/gitlab-org/gitlab/-/issues/22761), set the value of - `expire_in` to `never`. - -After their expiry, artifacts are deleted hourly by default (using a cron job), and are not -accessible anymore. - -#### `artifacts:expose_as` - -> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/15018) in GitLab 12.5. - -Use the `expose_as` keyword to expose [job artifacts](../pipelines/job_artifacts.md) -in the [merge request](../../user/project/merge_requests/index.md) UI. - -For example, to match a single file: - -```yaml -test: - script: ["echo 'test' > file.txt"] - artifacts: - expose_as: 'artifact 1' - paths: ['file.txt'] -``` - -With this configuration, GitLab adds a link **artifact 1** to the relevant merge request -that points to `file1.txt`. To access the link, select **View exposed artifact** -below the pipeline graph in the merge request overview. - -An example that matches an entire directory: - -```yaml -test: - script: ["mkdir test && echo 'test' > test/file.txt"] - artifacts: - expose_as: 'artifact 1' - paths: ['test/'] -``` - -Note the following: - -- Artifacts do not display in the merge request UI when using variables to define the `artifacts:paths`. -- A maximum of 10 job artifacts per merge request can be exposed. -- Glob patterns are unsupported. -- If a directory is specified, the link is to the job [artifacts browser](../pipelines/job_artifacts.md#download-job-artifacts) if there is more than - one file in the directory. -- For exposed single file artifacts with `.html`, `.htm`, `.txt`, `.json`, `.xml`, - and `.log` extensions, if [GitLab Pages](../../administration/pages/index.md) is: - - Enabled, GitLab automatically renders the artifact. - - Not enabled, the file is displayed in the artifacts browser. - -#### `artifacts:name` - -Use the `name` directive to define the name of the created artifacts -archive. You can specify a unique name for every archive. The `artifacts:name` -variable can make use of any of the [predefined variables](../variables/index.md). -The default name is `artifacts`, which becomes `artifacts.zip` when you download it. - -To create an archive with a name of the current job: - -```yaml -job: - artifacts: - name: "$CI_JOB_NAME" - paths: - - binaries/ -``` - -To create an archive with a name of the current branch or tag including only -the binaries directory: - -```yaml -job: - artifacts: - name: "$CI_COMMIT_REF_NAME" - paths: - - binaries/ -``` - -If your branch-name contains forward slashes -(for example `feature/my-feature`) it's advised to use `$CI_COMMIT_REF_SLUG` -instead of `$CI_COMMIT_REF_NAME` for proper naming of the artifact. - -To create an archive with a name of the current job and the current branch or -tag including only the binaries directory: - -```yaml -job: - artifacts: - name: "$CI_JOB_NAME-$CI_COMMIT_REF_NAME" - paths: - - binaries/ -``` - -To create an archive with a name of the current [stage](#stages) and branch name: - -```yaml -job: - artifacts: - name: "$CI_JOB_STAGE-$CI_COMMIT_REF_NAME" - paths: - - binaries/ -``` - ---- - -If you use **Windows Batch** to run your shell scripts you need to replace -`$` with `%`: - -```yaml -job: - artifacts: - name: "%CI_JOB_STAGE%-%CI_COMMIT_REF_NAME%" - paths: - - binaries/ -``` - -If you use **Windows PowerShell** to run your shell scripts you need to replace -`$` with `$env:`: - -```yaml -job: - artifacts: - name: "$env:CI_JOB_STAGE-$env:CI_COMMIT_REF_NAME" - paths: - - binaries/ -``` - -#### `artifacts:paths` - -Paths are relative to the project directory (`$CI_PROJECT_DIR`) and can't directly -link outside it. You can use Wildcards that use [glob](https://en.wikipedia.org/wiki/Glob_(programming)) -patterns and: - -- In [GitLab Runner 13.0](https://gitlab.com/gitlab-org/gitlab-runner/-/issues/2620) and later, -[`doublestar.Glob`](https://pkg.go.dev/github.com/bmatcuk/doublestar@v1.2.2?tab=doc#Match). -- In GitLab Runner 12.10 and earlier, -[`filepath.Match`](https://pkg.go.dev/path/filepath#Match). - -To restrict which jobs a specific job fetches artifacts from, see [dependencies](#dependencies). - -Send all files in `binaries` and `.config`: - -```yaml -artifacts: - paths: - - binaries/ - - .config -``` - -To disable artifact passing, define the job with empty [dependencies](#dependencies): - -```yaml -job: - stage: build - script: make build - dependencies: [] -``` - -You may want to create artifacts only for tagged releases to avoid filling the -build server storage with temporary build artifacts. - -Create artifacts only for tags (`default-job` doesn't create artifacts): - -```yaml -default-job: - script: - - mvn test -U - rules: - - if: $CI_COMMIT_BRANCH - -release-job: - script: - - mvn package -U - artifacts: - paths: - - target/*.war - rules: - - if: $CI_COMMIT_TAG -``` - -You can use wildcards for directories too. For example, if you want to get all the files inside the directories that end with `xyz`: - -```yaml -job: - artifacts: - paths: - - path/*xyz/* -``` - -#### `artifacts:public` - -> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/49775) in GitLab 13.8 -> - It's [deployed behind a feature flag](../../user/feature_flags.md), disabled by default. -> - It's disabled on GitLab.com. -> - It's recommended for production use. - -Use `artifacts:public` to determine whether the job artifacts should be -publicly available. - -The default for `artifacts:public` is `true` which means that the artifacts in -public pipelines are available for download by anonymous and guest users: - -```yaml -artifacts: - public: true -``` - -To deny read access for anonymous and guest users to artifacts in public -pipelines, set `artifacts:public` to `false`: - -```yaml -artifacts: - public: false -``` - -#### `artifacts:reports` - -> - [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/20390) in GitLab 11.2. -> - Requires GitLab Runner 11.2 and above. - -Use [`artifacts:reports`](#artifactsreports) -to collect test reports, code quality reports, and security reports from jobs. -It also exposes these reports in the GitLab UI (merge requests, pipeline views, and security dashboards). - -The test reports are collected regardless of the job results (success or failure). -You can use [`artifacts:expire_in`](#artifactsexpire_in) to set up an expiration -date for their artifacts. - -If you also want the ability to browse the report output files, include the -[`artifacts:paths`](#artifactspaths) keyword. - -##### `artifacts:reports:api_fuzzing` **(ULTIMATE)** - -> - Introduced in GitLab 13.4. -> - Requires GitLab Runner 13.4 or later. - -The `api_fuzzing` report collects [API Fuzzing bugs](../../user/application_security/api_fuzzing/index.md) -as artifacts. - -The collected API Fuzzing report uploads to GitLab as an artifact and is summarized in merge -requests and the pipeline view. It's also used to provide data for security dashboards. - -##### `artifacts:reports:cobertura` - -> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/3708) in GitLab 12.9. -> - Requires [GitLab Runner](https://docs.gitlab.com/runner/) 11.5 and above. - -The `cobertura` report collects [Cobertura coverage XML files](../../user/project/merge_requests/test_coverage_visualization.md). -The collected Cobertura coverage reports upload to GitLab as an artifact -and display in merge requests. - -Cobertura was originally developed for Java, but there are many -third party ports for other languages like JavaScript, Python, Ruby, and so on. - -##### `artifacts:reports:codequality` - -> - Introduced in GitLab 11.5. -> - [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/212499) to GitLab Free in 13.2. -> - Requires GitLab Runner 11.5 and above. - -The `codequality` report collects [Code Quality issues](../../user/project/merge_requests/code_quality.md) -as artifacts. - -The collected Code Quality report uploads to GitLab as an artifact and is summarized in merge requests. - -##### `artifacts:reports:container_scanning` **(ULTIMATE)** - -> - Introduced in GitLab 11.5. -> - Requires GitLab Runner 11.5 and above. - -The `container_scanning` report collects [Container Scanning vulnerabilities](../../user/application_security/container_scanning/index.md) -as artifacts. - -The collected Container Scanning report uploads to GitLab as an artifact and -is summarized in merge requests and the pipeline view. It's also used to provide data for security -dashboards. - -##### `artifacts:reports:coverage_fuzzing` **(ULTIMATE)** - -> - Introduced in GitLab 13.4. -> - Requires GitLab Runner 13.4 or later. - -The `coverage_fuzzing` report collects [coverage fuzzing bugs](../../user/application_security/coverage_fuzzing/index.md) -as artifacts. - -The collected coverage fuzzing report uploads to GitLab as an artifact and is summarized in merge -requests and the pipeline view. It's also used to provide data for security dashboards. - -##### `artifacts:reports:dast` **(ULTIMATE)** - -> - Introduced in GitLab 11.5. -> - Requires GitLab Runner 11.5 and above. - -The `dast` report collects [DAST vulnerabilities](../../user/application_security/dast/index.md) -as artifacts. - -The collected DAST report uploads to GitLab as an artifact and is summarized in merge requests and the pipeline view. It's also used to provide data for security -dashboards. - -##### `artifacts:reports:dependency_scanning` **(ULTIMATE)** - -> - Introduced in GitLab 11.5. -> - Requires GitLab Runner 11.5 and above. - -The `dependency_scanning` report collects [Dependency Scanning vulnerabilities](../../user/application_security/dependency_scanning/index.md) -as artifacts. - -The collected Dependency Scanning report uploads to GitLab as an artifact and is summarized in merge requests and the pipeline view. It's also used to provide data for security -dashboards. - -##### `artifacts:reports:dotenv` - -> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/17066) in GitLab 12.9. -> - Requires GitLab Runner 11.5 and later. - -The `dotenv` report collects a set of environment variables as artifacts. - -The collected variables are registered as runtime-created variables of the job, -which is useful to [set dynamic environment URLs after a job finishes](../environments/index.md#set-dynamic-environment-urls-after-a-job-finishes). - -There are a couple of exceptions to the [original dotenv rules](https://github.com/motdotla/dotenv#rules): - -- The variable key can contain only letters, digits, and underscores (`_`). -- The maximum size of the `.env` file is 5 KB. -- In GitLab 13.5 and older, the maximum number of inherited variables is 10. -- In [GitLab 13.6 and later](https://gitlab.com/gitlab-org/gitlab/-/issues/247913), - the maximum number of inherited variables is 20. -- Variable substitution in the `.env` file is not supported. -- The `.env` file can't have empty lines or comments (starting with `#`). -- Key values in the `env` file cannot have spaces or newline characters (`\n`), including when using single or double quotes. -- Quote escaping during parsing (`key = 'value'` -> `{key: "value"}`) is not supported. - -##### `artifacts:reports:junit` - -> - [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/20390) in GitLab 11.2. -> - Requires GitLab Runner 11.2 and above. - -The `junit` report collects [JUnit report format XML files](https://www.ibm.com/support/knowledgecenter/en/SSQ2R2_14.1.0/com.ibm.rsar.analysis.codereview.cobol.doc/topics/cac_useresults_junit.html) -as artifacts. Although JUnit was originally developed in Java, there are many -third party ports for other -languages like JavaScript, Python, Ruby, and so on. - -See [Unit test reports](../unit_test_reports.md) for more details and examples. -Below is an example of collecting a JUnit report format XML file from Ruby's RSpec test tool: - -```yaml -rspec: - stage: test - script: - - bundle install - - rspec --format RspecJunitFormatter --out rspec.xml - artifacts: - reports: - junit: rspec.xml -``` - -The collected Unit test reports upload to GitLab as an artifact and display in merge requests. - -If the JUnit tool you use exports to multiple XML files, specify -multiple test report paths within a single job to -concatenate them into a single file. Use a filename pattern (`junit: rspec-*.xml`), -an array of filenames (`junit: [rspec-1.xml, rspec-2.xml, rspec-3.xml]`), or a -combination thereof (`junit: [rspec.xml, test-results/TEST-*.xml]`). - -##### `artifacts:reports:license_scanning` **(ULTIMATE)** - -> - Introduced in GitLab 12.8. -> - Requires GitLab Runner 11.5 and above. - -The `license_scanning` report collects [Licenses](../../user/compliance/license_compliance/index.md) -as artifacts. - -The License Compliance report uploads to GitLab as an artifact and displays automatically in merge requests and the pipeline view, and provide data for security -dashboards. - -##### `artifacts:reports:load_performance` **(PREMIUM)** - -> - Introduced in [GitLab 13.2](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/35260) in [GitLab Premium](https://about.gitlab.com/pricing/) 13.2. -> - Requires GitLab Runner 11.5 and above. - -The `load_performance` report collects [Load Performance Testing metrics](../../user/project/merge_requests/load_performance_testing.md) -as artifacts. - -The report is uploaded to GitLab as an artifact and is -shown in merge requests automatically. - -##### `artifacts:reports:metrics` **(PREMIUM)** - -> Introduced in GitLab 11.10. - -The `metrics` report collects [Metrics](../metrics_reports.md) -as artifacts. - -The collected Metrics report uploads to GitLab as an artifact and displays in merge requests. - -##### `artifacts:reports:browser_performance` **(PREMIUM)** - -> - Introduced in GitLab 11.5. -> - Requires GitLab Runner 11.5 and above. -> - [Name changed](https://gitlab.com/gitlab-org/gitlab/-/issues/225914) from `artifacts:reports:performance` in GitLab 14.0. - -The `browser_performance` report collects [Browser Performance Testing metrics](../../user/project/merge_requests/browser_performance_testing.md) -as artifacts. - -The collected Browser Performance report uploads to GitLab as an artifact and displays in merge requests. - -##### `artifacts:reports:requirements` **(ULTIMATE)** - -> - [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/2859) in GitLab 13.1. -> - Requires GitLab Runner 11.5 and above. - -The `requirements` report collects `requirements.json` files as artifacts. - -The collected Requirements report uploads to GitLab as an artifact and -existing [requirements](../../user/project/requirements/index.md) are -marked as Satisfied. - -##### `artifacts:reports:sast` - -> - Introduced in GitLab 11.5. -> - Made [available in all tiers](https://gitlab.com/groups/gitlab-org/-/epics/2098) in GitLab 13.3. -> - Requires GitLab Runner 11.5 and above. - -The `sast` report collects [SAST vulnerabilities](../../user/application_security/sast/index.md) -as artifacts. - -The collected SAST report uploads to GitLab as an artifact and is summarized -in merge requests and the pipeline view. It's also used to provide data for security -dashboards. - -##### `artifacts:reports:secret_detection` - -> - Introduced in GitLab 13.1. -> - Made [available in all tiers](https://gitlab.com/gitlab-org/gitlab/-/issues/222788) in GitLab - 13.3. -> - Requires GitLab Runner 11.5 and above. - -The `secret-detection` report collects [detected secrets](../../user/application_security/secret_detection/index.md) -as artifacts. - -The collected Secret Detection report is uploaded to GitLab as an artifact and summarized -in the merge requests and pipeline view. It's also used to provide data for security -dashboards. - -##### `artifacts:reports:terraform` - -> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/207528) in GitLab 13.0. -> - Requires [GitLab Runner](https://docs.gitlab.com/runner/) 11.5 and above. - -The `terraform` report obtains a Terraform `tfplan.json` file. [JQ processing required to remove credentials](../../user/infrastructure/mr_integration.md#setup). The collected Terraform -plan report uploads to GitLab as an artifact and displays -in merge requests. For more information, see -[Output `terraform plan` information into a merge request](../../user/infrastructure/mr_integration.md). - -#### `artifacts:untracked` - -Use `artifacts:untracked` to add all Git untracked files as artifacts (along -with the paths defined in `artifacts:paths`). `artifacts:untracked` ignores configuration -in the repository's `.gitignore` file. - -Send all Git untracked files: - -```yaml -artifacts: - untracked: true -``` - -Send all Git untracked files and files in `binaries`: - -```yaml -artifacts: - untracked: true - paths: - - binaries/ -``` - -Send all untracked files but [exclude](#artifactsexclude) `*.txt`: - -```yaml -artifacts: - untracked: true - exclude: - - "*.txt" -``` - -#### `artifacts:when` - -Use `artifacts:when` to upload artifacts on job failure or despite the -failure. - -`artifacts:when` can be set to one of the following values: - -1. `on_success` (default): Upload artifacts only when the job succeeds. -1. `on_failure`: Upload artifacts only when the job fails. -1. `always`: Always upload artifacts. Useful, for example, when - [uploading artifacts](../unit_test_reports.md#viewing-junit-screenshots-on-gitlab) required to - troubleshoot failing tests. - -For example, to upload artifacts only when a job fails: - -```yaml -job: - artifacts: - when: on_failure -``` - -### `coverage` - -Use `coverage` to configure how code coverage is extracted from the -job output. - -Regular expressions are the only valid kind of value expected here. So, using -surrounding `/` is mandatory to consistently and explicitly represent -a regular expression string. You must escape special characters if you want to -match them literally. - -For example: - -```yaml -job1: - script: rspec - coverage: '/Code coverage: \d+\.\d+/' -``` - -The coverage is shown in the UI if at least one line in the job output matches the regular expression. -If there is more than one matched line in the job output, the last line is used. -For the matched line, the first occurrence of `\d+(\.\d+)?` is the code coverage. -Leading zeros are removed. - -Coverage output from [child pipelines](../parent_child_pipelines.md) is not recorded -or displayed. Check [the related issue](https://gitlab.com/gitlab-org/gitlab/-/issues/280818) -for more details. - -### `retry` - -> [Introduced](https://gitlab.com/gitlab-org/gitlab-runner/-/issues/3515) in GitLab 11.5, you can control which failures to retry on. - -Use `retry` to configure how many times a job is retried in -case of a failure. - -When a job fails, the job is processed again, -until the limit specified by the `retry` keyword is reached. - -If `retry` is set to `2`, and a job succeeds in a second run (first retry), it is not retried. -The `retry` value must be a positive integer, from `0` to `2` -(two retries maximum, three runs in total). - -The following example retries all failure cases: - -```yaml -test: - script: rspec - retry: 2 -``` - -By default, a job is retried on all failure cases. To have better control -over which failures to retry, `retry` can be a hash with the following keys: - -- `max`: The maximum number of retries. -- `when`: The failure cases to retry. - -To retry only runner system failures at maximum two times: - -```yaml -test: - script: rspec - retry: - max: 2 - when: runner_system_failure -``` - -If there is another failure, other than a runner system failure, the job -is not retried. - -To retry on multiple failure cases, `when` can also be an array of failures: - -```yaml -test: - script: rspec - retry: - max: 2 - when: - - runner_system_failure - - stuck_or_timeout_failure -``` - -Possible values for `when` are: - - - -- `always`: Retry on any failure (default). -- `unknown_failure`: Retry when the failure reason is unknown. -- `script_failure`: Retry when the script failed. -- `api_failure`: Retry on API failure. -- `stuck_or_timeout_failure`: Retry when the job got stuck or timed out. -- `runner_system_failure`: Retry if there is a runner system failure (for example, job setup failed). -- `missing_dependency_failure`: Retry if a dependency is missing. -- `runner_unsupported`: Retry if the runner is unsupported. -- `stale_schedule`: Retry if a delayed job could not be executed. -- `job_execution_timeout`: Retry if the script exceeded the maximum execution time set for the job. -- `archived_failure`: Retry if the job is archived and can't be run. -- `unmet_prerequisites`: Retry if the job failed to complete prerequisite tasks. -- `scheduler_failure`: Retry if the scheduler failed to assign the job to a runner. -- `data_integrity_failure`: Retry if there is a structural integrity problem detected. - -You can specify the number of [retry attempts for certain stages of job execution](../runners/configure_runners.md#job-stages-attempts) using variables. - -### `timeout` - -> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/14887) in GitLab 12.3. - -Use `timeout` to configure a timeout for a specific job. For example: - -```yaml -build: - script: build.sh - timeout: 3 hours 30 minutes - -test: - script: rspec - timeout: 3h 30m -``` - -The job-level timeout can exceed the -[project-level timeout](../pipelines/settings.md#timeout) but can't -exceed the runner-specific timeout. - -### `parallel` - -> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/21480) in GitLab 11.5. - -Use `parallel` to configure how many instances of a job to run in parallel. -The value can be from 2 to 50. - -The `parallel` keyword creates N instances of the same job that run in parallel. -They are named sequentially from `job_name 1/N` to `job_name N/N`: - -```yaml -test: - script: rspec - parallel: 5 -``` - -Every parallel job has a `CI_NODE_INDEX` and `CI_NODE_TOTAL` -[predefined CI/CD variable](../variables/index.md#predefined-cicd-variables) set. - -Different languages and test suites have different methods to enable parallelization. -For example, use [Semaphore Test Boosters](https://github.com/renderedtext/test-boosters) -and RSpec to run Ruby tests in parallel: - -```ruby -# Gemfile -source 'https://rubygems.org' - -gem 'rspec' -gem 'semaphore_test_boosters' -``` - -```yaml -test: - parallel: 3 - script: - - bundle - - bundle exec rspec_booster --job $CI_NODE_INDEX/$CI_NODE_TOTAL -``` - -WARNING: -Test Boosters reports usage statistics to the author. - -You can then navigate to the **Jobs** tab of a new pipeline build and see your RSpec -job split into three separate jobs. - -#### Parallel `matrix` jobs - -> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/15356) in GitLab 13.3. - -Use `matrix:` to run a job multiple times in parallel in a single pipeline, -but with different variable values for each instance of the job. -There can be from 2 to 50 jobs. - -Jobs can only run in parallel if there are multiple runners, or a single runner is -[configured to run multiple jobs concurrently](#use-your-own-runners). - -Every job gets the same `CI_NODE_TOTAL` [CI/CD variable](../variables/index.md#predefined-cicd-variables) value, and a unique `CI_NODE_INDEX` value. - -```yaml -deploystacks: - stage: deploy - script: - - bin/deploy - parallel: - matrix: - - PROVIDER: aws - STACK: - - monitoring - - app1 - - app2 - - PROVIDER: ovh - STACK: [monitoring, backup, app] - - PROVIDER: [gcp, vultr] - STACK: [data, processing] -``` - -The following example generates 10 parallel `deploystacks` jobs, each with different values -for `PROVIDER` and `STACK`: - -```plaintext -deploystacks: [aws, monitoring] -deploystacks: [aws, app1] -deploystacks: [aws, app2] -deploystacks: [ovh, monitoring] -deploystacks: [ovh, backup] -deploystacks: [ovh, app] -deploystacks: [gcp, data] -deploystacks: [gcp, processing] -deploystacks: [vultr, data] -deploystacks: [vultr, processing] -``` - -The job naming style was [improved in GitLab 13.4](https://gitlab.com/gitlab-org/gitlab/-/issues/230452). - -##### One-dimensional `matrix` jobs - -> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/26362) in GitLab 13.5. - -You can also have one-dimensional matrices with a single job: - -```yaml -deploystacks: - stage: deploy - script: - - bin/deploy - parallel: - matrix: - - PROVIDER: [aws, ovh, gcp, vultr] -``` - -##### Parallel `matrix` trigger jobs - -> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/270957) in GitLab 13.10. - -Use `matrix:` to run a [trigger](#trigger) job multiple times in parallel in a single pipeline, -but with different variable values for each instance of the job. - -```yaml -deploystacks: - stage: deploy - trigger: - include: path/to/child-pipeline.yml - parallel: - matrix: - - PROVIDER: aws - STACK: [monitoring, app1] - - PROVIDER: ovh - STACK: [monitoring, backup] - - PROVIDER: [gcp, vultr] - STACK: [data] -``` - -This example generates 6 parallel `deploystacks` trigger jobs, each with different values -for `PROVIDER` and `STACK`, and they create 6 different child pipelines with those variables. - -```plaintext -deploystacks: [aws, monitoring] -deploystacks: [aws, app1] -deploystacks: [ovh, monitoring] -deploystacks: [ovh, backup] -deploystacks: [gcp, data] -deploystacks: [vultr, data] -``` - -### `trigger` - -> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/8997) in [GitLab Premium](https://about.gitlab.com/pricing/) 11.8. -> - [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/199224) to GitLab Free in 12.8. - -Use `trigger` to define a downstream pipeline trigger. When GitLab starts a `trigger` job, -a downstream pipeline is created. - -Jobs with `trigger` can only use a [limited set of keywords](../multi_project_pipelines.md#define-multi-project-pipelines-in-your-gitlab-ciyml-file). -For example, you can't run commands with [`script`](#script), [`before_script`](#before_script), -or [`after_script`](#after_script). - -You can use this keyword to create two different types of downstream pipelines: - -- [Multi-project pipelines](../multi_project_pipelines.md#define-multi-project-pipelines-in-your-gitlab-ciyml-file) -- [Child pipelines](../parent_child_pipelines.md) - -[In GitLab 13.2](https://gitlab.com/gitlab-org/gitlab/-/issues/197140/) and later, you can -view which job triggered a downstream pipeline. In the [pipeline graph](../pipelines/index.md#visualize-pipelines), -hover over the downstream pipeline job. - -In [GitLab 13.5](https://gitlab.com/gitlab-org/gitlab/-/issues/201938) and later, you -can use [`when:manual`](#whenmanual) in the same job as `trigger`. In GitLab 13.4 and -earlier, using them together causes the error `jobs:#{job-name} when should be on_success, on_failure or always`. -You [cannot start `manual` trigger jobs with the API](https://gitlab.com/gitlab-org/gitlab/-/issues/284086). - -#### Basic `trigger` syntax for multi-project pipelines - -You can configure a downstream trigger by using the `trigger` keyword -with a full path to a downstream project: - -```yaml -rspec: - stage: test - script: bundle exec rspec - -staging: - stage: deploy - trigger: my/deployment -``` - -#### Complex `trigger` syntax for multi-project pipelines - -You can configure a branch name that GitLab uses to create -a downstream pipeline with: - -```yaml -rspec: - stage: test - script: bundle exec rspec - -staging: - stage: deploy - trigger: - project: my/deployment - branch: stable -``` - -To mirror the status from a triggered pipeline: - -```yaml -trigger_job: - trigger: - project: my/project - strategy: depend -``` - -To mirror the status from an upstream pipeline: - -```yaml -upstream_bridge: - stage: test - needs: - pipeline: other/project -``` - -#### `trigger` syntax for child pipeline - -> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/16094) in GitLab 12.7. - -To create a [child pipeline](../parent_child_pipelines.md), specify the path to the -YAML file that contains the configuration of the child pipeline: - -```yaml -trigger_job: - trigger: - include: path/to/child-pipeline.yml -``` - -Similar to [multi-project pipelines](../multi_project_pipelines.md#mirror-status-of-a-triggered-pipeline-in-the-trigger-job), -it's possible to mirror the status from a triggered pipeline: - -```yaml -trigger_job: - trigger: - include: - - local: path/to/child-pipeline.yml - strategy: depend -``` - -##### Trigger child pipeline with generated configuration file - -> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/35632) in GitLab 12.9. - -You can also trigger a child pipeline from a [dynamically generated configuration file](../parent_child_pipelines.md#dynamic-child-pipelines): - -```yaml -generate-config: - stage: build - script: generate-ci-config > generated-config.yml - artifacts: - paths: - - generated-config.yml - -child-pipeline: - stage: test - trigger: - include: - - artifact: generated-config.yml - job: generate-config -``` - -The `generated-config.yml` is extracted from the artifacts and used as the configuration -for triggering the child pipeline. - -##### Trigger child pipeline with files from another project - -> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/205157) in GitLab 13.5. - -To trigger child pipelines with files from another private project under the same -GitLab instance, use [`include:file`](#includefile): - -```yaml -child-pipeline: - trigger: - include: - - project: 'my-group/my-pipeline-library' - ref: 'main' - file: '/path/to/child-pipeline.yml' -``` - -#### Linking pipelines with `trigger:strategy` - -By default, the `trigger` job completes with the `success` status -as soon as the downstream pipeline is created. - -To force the `trigger` job to wait for the downstream (multi-project or child) pipeline to complete, use -`strategy: depend`. This setting makes the trigger job wait with a "running" status until the triggered -pipeline completes. At that point, the `trigger` job completes and displays the same status as -the downstream job. - -This setting can help keep your pipeline execution linear. In the following example, jobs from -subsequent stages wait for the triggered pipeline to successfully complete before -starting, which reduces parallelization. - -```yaml -trigger_job: - trigger: - include: path/to/child-pipeline.yml - strategy: depend -``` - -#### Trigger a pipeline by API call - -To force a rebuild of a specific branch, tag, or commit, you can use an API call -with a trigger token. - -The trigger token is different than the [`trigger`](#trigger) keyword. - -[Read more in the triggers documentation.](../triggers/index.md) - -### `interruptible` - -> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/32022) in GitLab 12.3. - -Use `interruptible` to indicate that a running job should be canceled if made redundant by a newer pipeline run. -Defaults to `false` (uninterruptible). Jobs that have not started yet (pending) are considered interruptible -and safe to be cancelled. -This value is used only if the [automatic cancellation of redundant pipelines feature](../pipelines/settings.md#auto-cancel-redundant-pipelines) -is enabled. - -When enabled, a pipeline is immediately canceled when a new pipeline starts on the same branch if either of the following is true: - -- All jobs in the pipeline are set as interruptible. -- Any uninterruptible jobs have not started yet. - -Set jobs as interruptible that can be safely canceled once started (for instance, a build job). - -In the following example, a new pipeline run causes an existing running pipeline to be: - -- Canceled, if only `step-1` is running or pending. -- Not canceled, once `step-2` starts running. - -After an uninterruptible job starts running, the pipeline cannot be canceled. - -```yaml -stages: - - stage1 - - stage2 - - stage3 - -step-1: - stage: stage1 - script: - - echo "Can be canceled." - interruptible: true - -step-2: - stage: stage2 - script: - - echo "Can not be canceled." - -step-3: - stage: stage3 - script: - - echo "Because step-2 can not be canceled, this step can never be canceled, even though it's set as interruptible." - interruptible: true -``` - -### `resource_group` - -> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/15536) in GitLab 12.7. - -Sometimes running multiple jobs or pipelines at the same time in an environment -can lead to errors during the deployment. - -To avoid these errors, use the `resource_group` attribute to make sure that -the runner doesn't run certain jobs simultaneously. Resource groups behave similar -to semaphores in other programming languages. - -When the `resource_group` keyword is defined for a job in the `.gitlab-ci.yml` file, -job executions are mutually exclusive across different pipelines for the same project. -If multiple jobs belonging to the same resource group are enqueued simultaneously, -only one of the jobs is picked by the runner. The other jobs wait until the -`resource_group` is free. - -For example: - -```yaml -deploy-to-production: - script: deploy - resource_group: production -``` - -In this case, two `deploy-to-production` jobs in two separate pipelines can never run at the same time. As a result, -you can ensure that concurrent deployments never happen to the production environment. - -You can define multiple resource groups per environment. For example, -when deploying to physical devices, you may have multiple physical devices. Each device -can be deployed to, but there can be only one deployment per device at any given time. - -The `resource_group` value can only contain letters, digits, `-`, `_`, `/`, `$`, `{`, `}`, `.`, and spaces. -It can't start or end with `/`. - -For more information, see [Deployments Safety](../environments/deployment_safety.md). - -#### Pipeline-level concurrency control with Cross-Project/Parent-Child pipelines - -> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/39057) in GitLab 13.9. - -You can define `resource_group` for downstream pipelines that are sensitive to concurrent -executions. The [`trigger` keyword](#trigger) can trigger downstream pipelines. The -[`resource_group` keyword](#resource_group) can co-exist with it. This is useful to control the -concurrency for deployment pipelines, while running non-sensitive jobs concurrently. - -The following example has two pipeline configurations in a project. When a pipeline starts running, -non-sensitive jobs are executed first and aren't affected by concurrent executions in other -pipelines. However, GitLab ensures that there are no other deployment pipelines running before -triggering a deployment (child) pipeline. If other deployment pipelines are running, GitLab waits -until those pipelines finish before running another one. - -```yaml -# .gitlab-ci.yml (parent pipeline) - -build: - stage: build - script: echo "Building..." - -test: - stage: test - script: echo "Testing..." - -deploy: - stage: deploy - trigger: - include: deploy.gitlab-ci.yml - strategy: depend - resource_group: AWS-production -``` - -```yaml -# deploy.gitlab-ci.yml (child pipeline) - -stages: - - provision - - deploy - -provision: - stage: provision - script: echo "Provisioning..." - -deployment: - stage: deploy - script: echo "Deploying..." -``` - -You must define [`strategy: depend`](#linking-pipelines-with-triggerstrategy) -with the `trigger` keyword. This ensures that the lock isn't released until the downstream pipeline -finishes. - -### `release` - -> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/19298) in GitLab 13.2. - -Use `release` to create a [release](../../user/project/releases/index.md). -Requires the [`release-cli`](https://gitlab.com/gitlab-org/release-cli/-/tree/master/docs) -to be available in your GitLab Runner Docker or shell executor. - -These keywords are supported: - -- [`tag_name`](#releasetag_name) -- [`description`](#releasedescription) -- [`name`](#releasename) (optional) -- [`ref`](#releaseref) (optional) -- [`milestones`](#releasemilestones) (optional) -- [`released_at`](#releasereleased_at) (optional) -- [`assets:links`](#releaseassetslinks) (optional) - -The release is created only if the job processes without error. If the Rails API -returns an error during release creation, the `release` job fails. - -#### `release-cli` Docker image - -You must specify the Docker image to use for the `release-cli`: - -```yaml -image: registry.gitlab.com/gitlab-org/release-cli:latest -``` - -#### `release-cli` for shell executors - -> [Introduced](https://gitlab.com/gitlab-org/release-cli/-/issues/21) in GitLab 13.8. - -For GitLab Runner shell executors, you can download and install the `release-cli` manually for your [supported OS and architecture](https://release-cli-downloads.s3.amazonaws.com/latest/index.html). -Once installed, the `release` keyword should be available to you. - -**Install on Unix/Linux** - -1. Download the binary for your system, in the following example for amd64 systems: - - ```shell - curl --location --output /usr/local/bin/release-cli "https://release-cli-downloads.s3.amazonaws.com/latest/release-cli-linux-amd64" - ``` - -1. Give it permissions to execute: - - ```shell - sudo chmod +x /usr/local/bin/release-cli - ``` - -1. Verify `release-cli` is available: - - ```shell - $ release-cli -v - - release-cli version 0.6.0 - ``` - -**Install on Windows PowerShell** - -1. Create a folder somewhere in your system, for example `C:\GitLab\Release-CLI\bin` - - ```shell - New-Item -Path 'C:\GitLab\Release-CLI\bin' -ItemType Directory - ``` - -1. Download the executable file: - - ```shell - PS C:\> Invoke-WebRequest -Uri "https://release-cli-downloads.s3.amazonaws.com/latest/release-cli-windows-amd64.exe" -OutFile "C:\GitLab\Release-CLI\bin\release-cli.exe" - - Directory: C:\GitLab\Release-CLI - Mode LastWriteTime Length Name - ---- ------------- ------ ---- - d----- 3/16/2021 4:17 AM bin - - ``` - -1. Add the directory to your `$env:PATH`: - - ```shell - $env:PATH += ";C:\GitLab\Release-CLI\bin" - ``` - -1. Verify `release-cli` is available: - - ```shell - PS C:\> release-cli -v - - release-cli version 0.6.0 - ``` - -#### Use a custom SSL CA certificate authority - -You can use the `ADDITIONAL_CA_CERT_BUNDLE` CI/CD variable to configure a custom SSL CA certificate authority, -which is used to verify the peer when the `release-cli` creates a release through the API using HTTPS with custom certificates. -The `ADDITIONAL_CA_CERT_BUNDLE` value should contain the -[text representation of the X.509 PEM public-key certificate](https://tools.ietf.org/html/rfc7468#section-5.1) -or the `path/to/file` containing the certificate authority. -For example, to configure this value in the `.gitlab-ci.yml` file, use the following: - -```yaml -release: - variables: - ADDITIONAL_CA_CERT_BUNDLE: | - -----BEGIN CERTIFICATE----- - MIIGqTCCBJGgAwIBAgIQI7AVxxVwg2kch4d56XNdDjANBgkqhkiG9w0BAQsFADCB - ... - jWgmPqF3vUbZE0EyScetPJquRFRKIesyJuBFMAs= - -----END CERTIFICATE----- - script: - - echo "Create release" - release: - name: 'My awesome release' - tag_name: '$CI_COMMIT_TAG' -``` - -The `ADDITIONAL_CA_CERT_BUNDLE` value can also be configured as a -[custom variable in the UI](../variables/index.md#custom-cicd-variables), -either as a `file`, which requires the path to the certificate, or as a variable, -which requires the text representation of the certificate. - -#### `script` - -All jobs except [trigger](#trigger) jobs must have the `script` keyword. A `release` -job can use the output from script commands, but you can use a placeholder script if -the script is not needed: - -```yaml -script: - - echo 'release job' -``` - -An [issue](https://gitlab.com/gitlab-org/gitlab/-/issues/223856) exists to remove this requirement in an upcoming version of GitLab. - -A pipeline can have multiple `release` jobs, for example: - -```yaml -ios-release: - script: - - echo 'iOS release job' - release: - tag_name: v1.0.0-ios - description: 'iOS release v1.0.0' - -android-release: - script: - - echo 'Android release job' - release: - tag_name: v1.0.0-android - description: 'Android release v1.0.0' -``` - -#### `release:tag_name` - -You must specify a `tag_name` for the release. The tag can refer to an existing Git tag or -you can specify a new tag. - -When the specified tag doesn't exist in the repository, a new tag is created from the associated SHA of the pipeline. - -For example, when creating a release from a Git tag: - -```yaml -job: - release: - tag_name: $CI_COMMIT_TAG - description: 'Release description' -``` - -It is also possible for the release job to automatically create a new unique tag. In that case, -do not use [`rules`](#rules) or [`only`](#only--except) to configure the job to -only run for tags. - -A semantic versioning example: - -```yaml -job: - release: - tag_name: ${MAJOR}_${MINOR}_${REVISION} - description: 'Release description' -``` - -- The release is created only if the job's main script succeeds. -- If the release already exists, it is not updated and the job with the `release` keyword fails. -- The `release` section executes after the `script` tag and before the `after_script`. - -#### `release:name` - -The release name. If omitted, it is populated with the value of `release: tag_name`. - -#### `release:description` - -Specifies the long description of the release. You can also specify a file that contains the -description. - -##### Read description from a file - -> [Introduced](https://gitlab.com/gitlab-org/release-cli/-/merge_requests/67) in GitLab 13.7. - -You can specify a file in `$CI_PROJECT_DIR` that contains the description. The file must be relative -to the project directory (`$CI_PROJECT_DIR`), and if the file is a symbolic link it can't reside -outside of `$CI_PROJECT_DIR`. The `./path/to/file` and filename can't contain spaces. - -```yaml -job: - release: - tag_name: ${MAJOR}_${MINOR}_${REVISION} - description: './path/to/CHANGELOG.md' -``` - -#### `release:ref` - -If the `release: tag_name` doesn't exist yet, the release is created from `ref`. -`ref` can be a commit SHA, another tag name, or a branch name. - -#### `release:milestones` - -The title of each milestone the release is associated with. - -#### `release:released_at` - -The date and time when the release is ready. Defaults to the current date and time if not -defined. Should be enclosed in quotes and expressed in ISO 8601 format. - -```json -released_at: '2021-03-15T08:00:00Z' -``` - -#### `release:assets:links` - -> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/271454) in GitLab 13.12. - -Include [asset links](../../user/project/releases/index.md#release-assets) in the release. - -NOTE: -Requires `release-cli` version v0.4.0 or higher. - -```yaml -assets: - links: - - name: 'asset1' - url: 'https://example.com/assets/1' - - name: 'asset2' - url: 'https://example.com/assets/2' - filepath: '/pretty/url/1' # optional - link_type: 'other' # optional -``` - -#### Complete example for `release` - -If you combine the previous examples for `release`, you get two options, depending on how you generate the -tags. You can't use these options together, so choose one: - -- To create a release when you push a Git tag, or when you add a Git tag - in the UI by going to **Repository > Tags**: - - ```yaml - release_job: - stage: release - image: registry.gitlab.com/gitlab-org/release-cli:latest - rules: - - if: $CI_COMMIT_TAG # Run this job when a tag is created manually - script: - - echo 'running release_job' - release: - name: 'Release $CI_COMMIT_TAG' - description: 'Created using the release-cli $EXTRA_DESCRIPTION' # $EXTRA_DESCRIPTION must be defined - tag_name: '$CI_COMMIT_TAG' # elsewhere in the pipeline. - ref: '$CI_COMMIT_TAG' - milestones: - - 'm1' - - 'm2' - - 'm3' - released_at: '2020-07-15T08:00:00Z' # Optional, is auto generated if not defined, or can use a variable. - assets: # Optional, multiple asset links - links: - - name: 'asset1' - url: 'https://example.com/assets/1' - - name: 'asset2' - url: 'https://example.com/assets/2' - filepath: '/pretty/url/1' # optional - link_type: 'other' # optional - ``` - -- To create a release automatically when commits are pushed or merged to the default branch, - using a new Git tag that is defined with variables: - - NOTE: - Environment variables set in `before_script` or `script` are not available for expanding - in the same job. Read more about - [potentially making variables available for expanding](https://gitlab.com/gitlab-org/gitlab-runner/-/issues/6400). - - ```yaml - prepare_job: - stage: prepare # This stage must run before the release stage - rules: - - if: $CI_COMMIT_TAG - when: never # Do not run this job when a tag is created manually - - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH # Run this job when commits are pushed or merged to the default branch - script: - - echo "EXTRA_DESCRIPTION=some message" >> variables.env # Generate the EXTRA_DESCRIPTION and TAG environment variables - - echo "TAG=v$(cat VERSION)" >> variables.env # and append to the variables.env file - artifacts: - reports: - dotenv: variables.env # Use artifacts:reports:dotenv to expose the variables to other jobs - - release_job: - stage: release - image: registry.gitlab.com/gitlab-org/release-cli:latest - needs: - - job: prepare_job - artifacts: true - rules: - - if: $CI_COMMIT_TAG - when: never # Do not run this job when a tag is created manually - - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH # Run this job when commits are pushed or merged to the default branch - script: - - echo 'running release_job for $TAG' - release: - name: 'Release $TAG' - description: 'Created using the release-cli $EXTRA_DESCRIPTION' # $EXTRA_DESCRIPTION and the $TAG - tag_name: '$TAG' # variables must be defined elsewhere - ref: '$CI_COMMIT_SHA' # in the pipeline. For example, in the - milestones: # prepare_job - - 'm1' - - 'm2' - - 'm3' - released_at: '2020-07-15T08:00:00Z' # Optional, is auto generated if not defined, or can use a variable. - assets: - links: - - name: 'asset1' - url: 'https://example.com/assets/1' - - name: 'asset2' - url: 'https://example.com/assets/2' - filepath: '/pretty/url/1' # optional - link_type: 'other' # optional - ``` - -#### Release assets as Generic packages - -You can use [Generic packages](../../user/packages/generic_packages/) to host your release assets. -For a complete example, see the [Release assets as Generic packages](https://gitlab.com/gitlab-org/release-cli/-/tree/master/docs/examples/release-assets-as-generic-package/) -project. - -#### `release-cli` command line - -The entries under the `release` node are transformed into a `bash` command line and sent -to the Docker container, which contains the [release-cli](https://gitlab.com/gitlab-org/release-cli). -You can also call the `release-cli` directly from a `script` entry. - -For example, if you use the YAML described previously: - -```shell -release-cli create --name "Release $CI_COMMIT_SHA" --description "Created using the release-cli $EXTRA_DESCRIPTION" --tag-name "v${MAJOR}.${MINOR}.${REVISION}" --ref "$CI_COMMIT_SHA" --released-at "2020-07-15T08:00:00Z" --milestone "m1" --milestone "m2" --milestone "m3" --assets-link "{\"name\":\"asset1\",\"url\":\"https://example.com/assets/1\",\"link_type\":\"other\"} -``` - -### `secrets` - -> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/33014) in GitLab 13.4. - -Use `secrets` to specify the [CI/CD Secrets](../secrets/index.md) the job needs. It should be a hash, -and the keys should be the names of the variables that are made available to the job. -The value of each secret is saved in a temporary file. This file's path is stored in these -variables. - -#### `secrets:vault` **(PREMIUM)** - -> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/28321) in GitLab 13.4. - -Use `vault` to specify secrets provided by [Hashicorp's Vault](https://www.vaultproject.io/). - -This syntax has multiple forms. The shortest form assumes the use of the -[KV-V2](https://www.vaultproject.io/docs/secrets/kv/kv-v2) secrets engine, -mounted at the default path `kv-v2`. The last part of the secret's path is the -field to fetch the value for: - -```yaml -job: - secrets: - DATABASE_PASSWORD: - vault: production/db/password # translates to secret `kv-v2/data/production/db`, field `password` -``` - -You can specify a custom secrets engine path by adding a suffix starting with `@`: - -```yaml -job: - secrets: - DATABASE_PASSWORD: - vault: production/db/password@ops # translates to secret `ops/data/production/db`, field `password` -``` - -In the detailed form of the syntax, you can specify all details explicitly: - -```yaml -job: - secrets: - DATABASE_PASSWORD: # translates to secret `ops/data/production/db`, field `password` - vault: - engine: - name: kv-v2 - path: ops - path: production/db - field: password -``` - -### `pages` - -Use `pages` to upload static content to GitLab. The content -is then published as a website. You must: - -- Place any static content in a `public/` directory. -- Define [`artifacts`](#artifacts) with a path to the `public/` directory. - -The following example moves all files from the root of the project to the -`public/` directory. The `.public` workaround is so `cp` does not also copy -`public/` to itself in an infinite loop: - -```yaml -pages: - stage: deploy - script: - - mkdir .public - - cp -r * .public - - mv .public public - artifacts: - paths: - - public - rules: - - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH -``` - -View the [GitLab Pages user documentation](../../user/project/pages/index.md). - -### `inherit` - -> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/207484) in GitLab 12.9. - -Use `inherit:` to control inheritance of globally-defined defaults -and variables. - -To enable or disable the inheritance of all `default:` or `variables:` keywords, use: - -- `default: true` or `default: false` -- `variables: true` or `variables: false` - -To inherit only a subset of `default:` keywords or `variables:`, specify what -you wish to inherit. Anything not listed is **not** inherited. Use -one of the following formats: - -```yaml -inherit: - default: [keyword1, keyword2] - variables: [VARIABLE1, VARIABLE2] -``` - -Or: - -```yaml -inherit: - default: - - keyword1 - - keyword2 - variables: - - VARIABLE1 - - VARIABLE2 -``` - -In the following example: - -- `rubocop`: - - inherits: Nothing. -- `rspec`: - - inherits: the default `image` and the `WEBHOOK_URL` variable. - - does **not** inherit: the default `before_script` and the `DOMAIN` variable. -- `capybara`: - - inherits: the default `before_script` and `image`. - - does **not** inherit: the `DOMAIN` and `WEBHOOK_URL` variables. -- `karma`: - - inherits: the default `image` and `before_script`, and the `DOMAIN` variable. - - does **not** inherit: `WEBHOOK_URL` variable. - -```yaml -default: - image: 'ruby:2.4' - before_script: - - echo Hello World - -variables: - DOMAIN: example.com - WEBHOOK_URL: https://my-webhook.example.com - -rubocop: - inherit: - default: false - variables: false - script: bundle exec rubocop - -rspec: - inherit: - default: [image] - variables: [WEBHOOK_URL] - script: bundle exec rspec - -capybara: - inherit: - variables: false - script: bundle exec capybara - -karma: - inherit: - default: true - variables: [DOMAIN] - script: karma -``` - -## `variables` - -> Introduced in GitLab Runner v0.5.0. - -[CI/CD variables](../variables/index.md) are configurable values that are passed to jobs. -They can be set globally and per-job. - -There are two types of variables. - -- [Custom variables](../variables/index.md#custom-cicd-variables): - You can define their values in the `.gitlab-ci.yml` file, in the GitLab UI, - or by using the API. You can also input variables in the GitLab UI when - [running a pipeline manually](../pipelines/index.md#run-a-pipeline-manually). -- [Predefined variables](../variables/predefined_variables.md): - These values are set by the runner itself. - One example is `CI_COMMIT_REF_NAME`, which is the branch or tag the project is built for. - -After you define a variable, you can use it in all executed commands and scripts. - -Variables are meant for non-sensitive project configuration, for example: - -```yaml -variables: - DEPLOY_SITE: "https://example.com/" - -deploy_job: - stage: deploy - script: - - deploy-script --url $DEPLOY_SITE --path "/" - -deploy_review_job: - stage: deploy - variables: - REVIEW_PATH: "/review" - script: - - deploy-review-script --url $DEPLOY_SITE --path $REVIEW_PATH -``` - -You can use only integers and strings for the variable's name and value. - -If you define a variable at the top level of the `gitlab-ci.yml` file, it is global, -meaning it applies to all jobs. If you define a variable in a job, it's available -to that job only. - -If a variable of the same name is defined globally and for a specific job, the -[job-specific variable overrides the global variable](../variables/index.md#cicd-variable-precedence). - -All YAML-defined variables are also set to any linked -[Docker service containers](../services/index.md). - -You can use [YAML anchors for variables](#yaml-anchors-for-variables). - -### Prefill variables in manual pipelines - -> [Introduced in](https://gitlab.com/gitlab-org/gitlab/-/issues/30101) GitLab 13.7. - -Use the `value` and `description` keywords to define [pipeline-level (global) variables that are prefilled](../pipelines/index.md#prefill-variables-in-manual-pipelines) -when [running a pipeline manually](../pipelines/index.md#run-a-pipeline-manually): - -```yaml -variables: - DEPLOY_ENVIRONMENT: - value: "staging" # Deploy to staging by default - description: "The deployment target. Change this variable to 'canary' or 'production' if needed." -``` - -You cannot set job-level variables to be pre-filled when you run a pipeline manually. - -### Configure runner behavior with variables - -You can use [CI/CD variables](../variables/index.md) to configure how the runner processes Git requests: - -- [`GIT_STRATEGY`](../runners/configure_runners.md#git-strategy) -- [`GIT_SUBMODULE_STRATEGY`](../runners/configure_runners.md#git-submodule-strategy) -- [`GIT_CHECKOUT`](../runners/configure_runners.md#git-checkout) -- [`GIT_CLEAN_FLAGS`](../runners/configure_runners.md#git-clean-flags) -- [`GIT_FETCH_EXTRA_FLAGS`](../runners/configure_runners.md#git-fetch-extra-flags) -- [`GIT_DEPTH`](../runners/configure_runners.md#shallow-cloning) (shallow cloning) -- [`GIT_CLONE_PATH`](../runners/configure_runners.md#custom-build-directories) (custom build directories) -- [`TRANSFER_METER_FREQUENCY`](../runners/configure_runners.md#artifact-and-cache-settings) (artifact/cache meter update frequency) -- [`ARTIFACT_COMPRESSION_LEVEL`](../runners/configure_runners.md#artifact-and-cache-settings) (artifact archiver compression level) -- [`CACHE_COMPRESSION_LEVEL`](../runners/configure_runners.md#artifact-and-cache-settings) (cache archiver compression level) - -You can also use variables to configure how many times a runner -[attempts certain stages of job execution](../runners/configure_runners.md#job-stages-attempts). - -## YAML-specific features - -In your `.gitlab-ci.yml` file, you can use YAML-specific features like anchors (`&`), aliases (`*`), -and map merging (`<<`). Use these features to reduce the complexity -of the code in the `.gitlab-ci.yml` file. - -Read more about the various [YAML features](https://learnxinyminutes.com/docs/yaml/). - -In most cases, the [`extends` keyword](#extends) is more user friendly and you should -use it when possible. - -You can use YAML anchors to merge YAML arrays. - -### Anchors - -YAML has a feature called 'anchors' that you can use to duplicate -content across your document. - -Use anchors to duplicate or inherit properties. Use anchors with [hidden jobs](#hide-jobs) -to provide templates for your jobs. When there are duplicate keys, GitLab -performs a reverse deep merge based on the keys. - -You can't use YAML anchors across multiple files when using the [`include`](#include) -keyword. Anchors are only valid in the file they were defined in. To reuse configuration -from different YAML files, use [`!reference` tags](#reference-tags) or the -[`extends` keyword](#extends). - -The following example uses anchors and map merging. It creates two jobs, -`test1` and `test2`, that inherit the `.job_template` configuration, each -with their own custom `script` defined: - -```yaml -.job_template: &job_configuration # Hidden yaml configuration that defines an anchor named 'job_configuration' - image: ruby:2.6 - services: - - postgres - - redis - -test1: - <<: *job_configuration # Merge the contents of the 'job_configuration' alias - script: - - test1 project - -test2: - <<: *job_configuration # Merge the contents of the 'job_configuration' alias - script: - - test2 project -``` - -`&` sets up the name of the anchor (`job_configuration`), `<<` means "merge the -given hash into the current one," and `*` includes the named anchor -(`job_configuration` again). The expanded version of this example is: - -```yaml -.job_template: - image: ruby:2.6 - services: - - postgres - - redis - -test1: - image: ruby:2.6 - services: - - postgres - - redis - script: - - test1 project - -test2: - image: ruby:2.6 - services: - - postgres - - redis - script: - - test2 project -``` - -You can use anchors to define two sets of services. For example, `test:postgres` -and `test:mysql` share the `script` defined in `.job_template`, but use different -`services`, defined in `.postgres_services` and `.mysql_services`: - -```yaml -.job_template: &job_configuration - script: - - test project - tags: - - dev - -.postgres_services: - services: &postgres_configuration - - postgres - - ruby - -.mysql_services: - services: &mysql_configuration - - mysql - - ruby - -test:postgres: - <<: *job_configuration - services: *postgres_configuration - tags: - - postgres - -test:mysql: - <<: *job_configuration - services: *mysql_configuration -``` - -The expanded version is: - -```yaml -.job_template: - script: - - test project - tags: - - dev - -.postgres_services: - services: - - postgres - - ruby - -.mysql_services: - services: - - mysql - - ruby - -test:postgres: - script: - - test project - services: - - postgres - - ruby - tags: - - postgres - -test:mysql: - script: - - test project - services: - - mysql - - ruby - tags: - - dev -``` - -You can see that the hidden jobs are conveniently used as templates, and -`tags: [postgres]` overwrites `tags: [dev]`. - -#### YAML anchors for scripts - -> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/23005) in GitLab 12.5. - -You can use [YAML anchors](#anchors) with [script](#script), [`before_script`](#before_script), -and [`after_script`](#after_script) to use predefined commands in multiple jobs: - -```yaml -.some-script-before: &some-script-before - - echo "Execute this script first" - -.some-script: &some-script - - echo "Execute this script second" - - echo "Execute this script too" - -.some-script-after: &some-script-after - - echo "Execute this script last" - -job1: - before_script: - - *some-script-before - script: - - *some-script - - echo "Execute something, for this job only" - after_script: - - *some-script-after - -job2: - script: - - *some-script-before - - *some-script - - echo "Execute something else, for this job only" - - *some-script-after -``` - -#### YAML anchors for variables - -Use [YAML anchors](#anchors) with `variables` to repeat assignment -of variables across multiple jobs. You can also use YAML anchors when a job -requires a specific `variables` block that would otherwise override the global variables. - -The following example shows how override the `GIT_STRATEGY` variable without affecting -the use of the `SAMPLE_VARIABLE` variable: - -```yaml -# global variables -variables: &global-variables - SAMPLE_VARIABLE: sample_variable_value - ANOTHER_SAMPLE_VARIABLE: another_sample_variable_value - -# a job that must set the GIT_STRATEGY variable, yet depend on global variables -job_no_git_strategy: - stage: cleanup - variables: - <<: *global-variables - GIT_STRATEGY: none - script: echo $SAMPLE_VARIABLE -``` - -### Hide jobs - -If you want to temporarily disable a job, rather than commenting out all the -lines where the job is defined: - -```yaml -# hidden_job: -# script: -# - run test -``` - -Instead, you can start its name with a dot (`.`) and it is not processed by -GitLab CI/CD. In the following example, `.hidden_job` is ignored: - -```yaml -.hidden_job: - script: - - run test -``` - -Use this feature to ignore jobs, or use the -[YAML-specific features](#yaml-specific-features) and transform the hidden jobs -into templates. - -### `!reference` tags - -> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/266173) in GitLab 13.9. - -Use the `!reference` custom YAML tag to select keyword configuration from other job -sections and reuse it in the current section. Unlike [YAML anchors](#anchors), you can -use `!reference` tags to reuse configuration from [included](#include) configuration -files as well. - -In the following example, a `script` and an `after_script` from two different locations are -reused in the `test` job: - -- `setup.yml`: - - ```yaml - .setup: - script: - - echo creating environment - ``` - -- `.gitlab-ci.yml`: - - ```yaml - include: - - local: setup.yml - - .teardown: - after_script: - - echo deleting environment - - test: - script: - - !reference [.setup, script] - - echo running my own command - after_script: - - !reference [.teardown, after_script] - ``` - -In the following example, `test-vars-1` reuses all the variables in `.vars`, while `test-vars-2` -selects a specific variable and reuses it as a new `MY_VAR` variable. - -```yaml -.vars: - variables: - URL: "http://my-url.internal" - IMPORTANT_VAR: "the details" - -test-vars-1: - variables: !reference [.vars, variables] - script: - - printenv - -test-vars-2: - variables: - MY_VAR: !reference [.vars, variables, IMPORTANT_VAR] - script: - - printenv -``` - -You can't reuse a section that already includes a `!reference` tag. Only one level -of nesting is supported. - -## Skip Pipeline - -To push a commit without triggering a pipeline, add `[ci skip]` or `[skip ci]`, using any -capitalization, to your commit message. - -Alternatively, if you are using Git 2.10 or later, use the `ci.skip` [Git push option](../../user/project/push_options.md#push-options-for-gitlab-cicd). -The `ci.skip` push option does not skip merge request -pipelines. - -## Processing Git pushes - -GitLab creates at most four branch and tag pipelines when -pushing multiple changes in a single `git push` invocation. - -This limitation does not affect any of the updated merge request pipelines. -All updated merge requests have a pipeline created when using -[pipelines for merge requests](../merge_request_pipelines/index.md). - -## Deprecated keywords - -The following keywords are deprecated. - -### Globally-defined `types` - -WARNING: -`types` is deprecated, and could be removed in a future release. -Use [`stages`](#stages) instead. - -### Job-defined `type` - -WARNING: -`type` is deprecated, and could be removed in one of the future releases. -Use [`stage`](#stage) instead. - -### Globally-defined `image`, `services`, `cache`, `before_script`, `after_script` - -Defining `image`, `services`, `cache`, `before_script`, and -`after_script` globally is deprecated. Support could be removed -from a future release. - -Use [`default:`](#custom-default-keyword-values) instead. For example: - -```yaml -default: - image: ruby:3.0 - services: - - docker:dind - cache: - paths: [vendor/] - before_script: - - bundle config set path vendor/bundle - - bundle install - after_script: - - rm -rf tmp/ -``` - - + + diff --git a/doc/ci/yaml/gitlab_ci_yaml.md b/doc/ci/yaml/gitlab_ci_yaml.md index 72e3f644d26..2723cb19c1f 100644 --- a/doc/ci/yaml/gitlab_ci_yaml.md +++ b/doc/ci/yaml/gitlab_ci_yaml.md @@ -13,7 +13,7 @@ type: reference To use GitLab CI/CD, you need: - Application code hosted in a Git repository. -- A file called [`.gitlab-ci.yml`](README.md) in the root of your repository, which +- A file called [`.gitlab-ci.yml`](index.md) in the root of your repository, which contains the CI/CD configuration. In the `.gitlab-ci.yml` file, you can define: @@ -27,7 +27,7 @@ In the `.gitlab-ci.yml` file, you can define: The scripts are grouped into **jobs**, and jobs run as part of a larger **pipeline**. You can group multiple independent jobs into **stages** that run in a defined order. -The CI/CD configuration needs at least one job that is [not hidden](README.md#hide-jobs). +The CI/CD configuration needs at least one job that is [not hidden](index.md#hide-jobs). You should organize your jobs in a sequence that suits your application and is in accordance with the tests you wish to perform. To [visualize](../pipeline_editor/index.md#visualize-ci-configuration) the process, imagine @@ -89,4 +89,4 @@ If anything goes wrong, you can ![rollback button](img/rollback.png) -[View the full syntax for the `.gitlab-ci.yml` file](README.md). +[View the full syntax for the `.gitlab-ci.yml` file](index.md). diff --git a/doc/ci/yaml/includes.md b/doc/ci/yaml/includes.md index 385d0fbb80a..673a4e75c35 100644 --- a/doc/ci/yaml/includes.md +++ b/doc/ci/yaml/includes.md @@ -7,8 +7,8 @@ type: reference # GitLab CI/CD include examples **(FREE)** -In addition to the [`includes` examples](README.md#include) listed in the -[GitLab CI YAML reference](README.md), this page lists more variations of `include` +In addition to the [`includes` examples](index.md#include) listed in the +[GitLab CI YAML reference](index.md), this page lists more variations of `include` usage. ## Single string or array of multiple values diff --git a/doc/ci/yaml/index.md b/doc/ci/yaml/index.md new file mode 100644 index 00000000000..5e1f44abf0e --- /dev/null +++ b/doc/ci/yaml/index.md @@ -0,0 +1,4829 @@ +--- +stage: Verify +group: Pipeline Execution +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 +--- + + + +# Keyword reference for the .gitlab-ci.yml file **(FREE)** + + + +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/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). + +When you are editing your `.gitlab-ci.yml` file, you can validate it with the +[CI Lint](../lint.md) tool. + +## Job keywords + +A job is defined as a list of keywords that define the job's behavior. + +The keywords available for jobs are: + +| Keyword | Description | +| :-----------------------------------|:------------| +| [`after_script`](#after_script) | Override a set of commands that are executed after job. | +| [`allow_failure`](#allow_failure) | Allow job to fail. A failed job does not cause the pipeline to fail. | +| [`artifacts`](#artifacts) | List of files and directories to attach to a job on success. | +| [`before_script`](#before_script) | Override a set of commands that are executed before job. | +| [`cache`](#cache) | List of files that should be cached between subsequent runs. | +| [`coverage`](#coverage) | Code coverage settings for a given job. | +| [`dependencies`](#dependencies) | Restrict which artifacts are passed to a specific job by providing a list of jobs to fetch artifacts from. | +| [`environment`](#environment) | Name of an environment to which the job deploys. | +| [`except`](#only--except) | Control when jobs are not created. | +| [`extends`](#extends) | Configuration entries that this job inherits from. | +| [`image`](#image) | Use Docker images. | +| [`include`](#include) | Include external YAML files. | +| [`inherit`](#inherit) | Select which global defaults all jobs inherit. | +| [`interruptible`](#interruptible) | Defines if a job can be canceled when made redundant by a newer run. | +| [`needs`](#needs) | Execute jobs earlier than the stage ordering. | +| [`only`](#only--except) | Control when jobs are created. | +| [`pages`](#pages) | Upload the result of a job to use with GitLab Pages. | +| [`parallel`](#parallel) | How many instances of a job should be run in parallel. | +| [`release`](#release) | Instructs the runner to generate a [release](../../user/project/releases/index.md) object. | +| [`resource_group`](#resource_group) | Limit job concurrency. | +| [`retry`](#retry) | When and how many times a job can be auto-retried in case of a failure. | +| [`rules`](#rules) | List of conditions to evaluate and determine selected attributes of a job, and whether or not it's created. | +| [`script`](#script) | Shell script that is executed by a runner. | +| [`secrets`](#secrets) | The CI/CD secrets the job needs. | +| [`services`](#services) | Use Docker services images. | +| [`stage`](#stage) | Defines a job stage. | +| [`tags`](#tags) | List of tags that are used to select a runner. | +| [`timeout`](#timeout) | Define a custom job-level timeout that takes precedence over the project-wide setting. | +| [`trigger`](#trigger) | Defines a downstream pipeline trigger. | +| [`variables`](#variables) | Define job variables on a job level. | +| [`when`](#when) | When to run job. | + +### Unavailable names for jobs + +You can't use these keywords as job names: + +- `image` +- `services` +- `stages` +- `types` +- `before_script` +- `after_script` +- `variables` +- `cache` +- `include` + +### Custom default keyword values + +You can set global defaults for some keywords. Jobs that do not define one or more +of the listed keywords use the value defined in the `default:` section. + +These job keywords can be defined inside a `default:` section: + +- [`after_script`](#after_script) +- [`artifacts`](#artifacts) +- [`before_script`](#before_script) +- [`cache`](#cache) +- [`image`](#image) +- [`interruptible`](#interruptible) +- [`retry`](#retry) +- [`services`](#services) +- [`tags`](#tags) +- [`timeout`](#timeout) + +The following example sets the `ruby:3.0` image as the default for all jobs in the pipeline. +The `rspec 2.7` job does not use the default, because it overrides the default with +a job-specific `image:` section: + +```yaml +default: + image: ruby:3.0 + +rspec: + script: bundle exec rspec + +rspec 2.7: + image: ruby:2.7 + script: bundle exec rspec +``` + +## Global keywords + +Some keywords are not defined in a job. These keywords control pipeline behavior +or import additional pipeline configuration: + +| Keyword | Description | +|-------------------------|:------------| +| [`stages`](#stages) | The names and order of the pipeline stages. | +| [`workflow`](#workflow) | Control what types of pipeline run. | +| [`include`](#include) | Import configuration from other YAML files. | + +### `stages` + +Use `stages` to define stages that contain groups of jobs. `stages` is defined globally +for the pipeline. Use [`stage`](#stage) in a job to define which stage the job is +part of. + +The order of the `stages` items defines the execution order for jobs: + +- Jobs in the same stage run in parallel. +- Jobs in the next stage run after the jobs from the previous stage complete successfully. + +For example: + +```yaml +stages: + - build + - test + - deploy +``` + +1. All jobs in `build` execute in parallel. +1. If all jobs in `build` succeed, the `test` jobs execute in parallel. +1. If all jobs in `test` succeed, the `deploy` jobs execute in parallel. +1. If all jobs in `deploy` succeed, the pipeline is marked as `passed`. + +If any job fails, the pipeline is marked as `failed` and jobs in later stages do not +start. Jobs in the current stage are not stopped and continue to run. + +If no `stages` are defined in the `.gitlab-ci.yml` file, then `build`, `test` and `deploy` +are the default pipeline stages. + +If a job does not specify a [`stage`](#stage), the job is assigned the `test` stage. + +If a stage is defined, but no jobs use it, the stage is not visible in the pipeline. This is +useful for [compliance pipeline configuration](../../user/project/settings/index.md#compliance-pipeline-configuration) +because: + +- Stages can be defined in the compliance configuration but remain hidden if not used. +- The defined stages become visible when developers use them in job definitions. + +To make a job start earlier and ignore the stage order, use +the [`needs`](#needs) keyword. + +### `workflow` + +> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/29654) in GitLab 12.5 + +Use `workflow:` to determine whether or not a pipeline is created. +Define this keyword at the top level, with a single `rules:` keyword that +is similar to [`rules:` defined in jobs](#rules). + +You can use the [`workflow:rules` templates](#workflowrules-templates) to import +a preconfigured `workflow: rules` entry. + +`workflow: rules` accepts these keywords: + +- [`if`](#rulesif): Check this rule to determine when to run a pipeline. +- [`when`](#when): Specify what to do when the `if` rule evaluates to true. + - To run a pipeline, set to `always`. + - To prevent pipelines from running, set to `never`. +- [`variables`](#workflowrulesvariables): If not defined, uses the [variables defined elsewhere](#variables). + +When no rules evaluate to true, the pipeline does not run. + +Some example `if` clauses for `workflow: rules`: + +| Example rules | Details | +|------------------------------------------------------|-----------------------------------------------------------| +| `if: '$CI_PIPELINE_SOURCE == "merge_request_event"'` | Control when merge request pipelines run. | +| `if: '$CI_PIPELINE_SOURCE == "push"'` | Control when both branch pipelines and tag pipelines run. | +| `if: $CI_COMMIT_TAG` | Control when tag pipelines run. | +| `if: $CI_COMMIT_BRANCH` | Control when branch pipelines run. | + +See the [common `if` clauses for `rules`](../jobs/job_control.md#common-if-clauses-for-rules) for more examples. + +In the following example, pipelines run for all `push` events (changes to +branches and new tags). Pipelines for push events with `-draft` in the commit message +don't run, because they are set to `when: never`. Pipelines for schedules or merge requests +don't run either, because no rules evaluate to true for them: + +```yaml +workflow: + rules: + - if: $CI_COMMIT_MESSAGE =~ /-draft$/ + when: never + - if: '$CI_PIPELINE_SOURCE == "push"' +``` + +This example has strict rules, and pipelines do **not** run in any other case. + +Alternatively, all of the rules can be `when: never`, with a final +`when: always` rule. Pipelines that match the `when: never` rules do not run. +All other pipeline types run: + +```yaml +workflow: + rules: + - if: '$CI_PIPELINE_SOURCE == "schedule"' + when: never + - if: '$CI_PIPELINE_SOURCE == "push"' + when: never + - when: always +``` + +This example prevents pipelines for schedules or `push` (branches and tags) pipelines. +The final `when: always` rule runs all other pipeline types, **including** merge +request pipelines. + +If your rules match both branch pipelines and merge request pipelines, +[duplicate pipelines](../jobs/job_control.md#avoid-duplicate-pipelines) can occur. + +#### `workflow:rules:variables` + +> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/294232) in GitLab 13.11. +> - [Feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/issues/300997) in GitLab 14.1. + +You can use [`variables`](#variables) in `workflow:rules:` to define variables for specific pipeline conditions. + +For example: + +```yaml +variables: + DEPLOY_VARIABLE: "default-deploy" + +workflow: + rules: + - if: $CI_COMMIT_REF_NAME == $CI_DEFAULT_BRANCH + variables: + DEPLOY_VARIABLE: "deploy-production" # Override globally-defined DEPLOY_VARIABLE + - if: $CI_COMMIT_REF_NAME =~ /feature/ + variables: + IS_A_FEATURE: "true" # Define a new variable. + - when: always # Run the pipeline in other cases + +job1: + variables: + DEPLOY_VARIABLE: "job1-default-deploy" + rules: + - if: $CI_COMMIT_REF_NAME == $CI_DEFAULT_BRANCH + variables: # Override DEPLOY_VARIABLE defined + DEPLOY_VARIABLE: "job1-deploy-production" # at the job level. + - when: on_success # Run the job in other cases + script: + - echo "Run script with $DEPLOY_VARIABLE as an argument" + - echo "Run another script if $IS_A_FEATURE exists" + +job2: + script: + - echo "Run script with $DEPLOY_VARIABLE as an argument" + - echo "Run another script if $IS_A_FEATURE exists" +``` + +When the branch is the default branch: + +- job1's `DEPLOY_VARIABLE` is `job1-deploy-production`. +- job2's `DEPLOY_VARIABLE` is `deploy-production`. + +When the branch is `feature`: + +- job1's `DEPLOY_VARIABLE` is `job1-default-deploy`, and `IS_A_FEATURE` is `true`. +- job2's `DEPLOY_VARIABLE` is `default-deploy`, and `IS_A_FEATURE` is `true`. + +When the branch is something else: + +- job1's `DEPLOY_VARIABLE` is `job1-default-deploy`. +- job2's `DEPLOY_VARIABLE` is `default-deploy`. + +#### `workflow:rules` templates + +> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/217732) in GitLab 13.0. + +GitLab provides templates that set up `workflow: rules` +for common scenarios. These templates help prevent duplicate pipelines. + +The [`Branch-Pipelines` template](https://gitlab.com/gitlab-org/gitlab/-/tree/master/lib/gitlab/ci/templates/Workflows/Branch-Pipelines.gitlab-ci.yml) +makes your pipelines run for branches and tags. + +Branch pipeline status is displayed in merge requests that use the branch +as a source. However, this pipeline type does not support any features offered by +[merge request pipelines](../merge_request_pipelines/), like +[pipelines for merged results](../merge_request_pipelines/pipelines_for_merged_results/index.md) +or [merge trains](../merge_request_pipelines/pipelines_for_merged_results/merge_trains/). +This template intentionally avoids those features. + +To [include](#include) it: + +```yaml +include: + - template: 'Workflows/Branch-Pipelines.gitlab-ci.yml' +``` + +The [`MergeRequest-Pipelines` template](https://gitlab.com/gitlab-org/gitlab/-/tree/master/lib/gitlab/ci/templates/Workflows/MergeRequest-Pipelines.gitlab-ci.yml) +makes your pipelines run for the default branch, tags, and +all types of merge request pipelines. Use this template if you use any of the +the [pipelines for merge requests features](../merge_request_pipelines/). + +To [include](#include) it: + +```yaml +include: + - template: 'Workflows/MergeRequest-Pipelines.gitlab-ci.yml' +``` + +#### Switch between branch pipelines and merge request pipelines + +> [Introduced in](https://gitlab.com/gitlab-org/gitlab/-/issues/201845) GitLab 13.8. + +To make the pipeline switch from branch pipelines to merge request pipelines after +a merge request is created, add a `workflow: rules` section to your `.gitlab-ci.yml` file. + +If you use both pipeline types at the same time, [duplicate pipelines](../jobs/job_control.md#avoid-duplicate-pipelines) +might run at the same time. To prevent duplicate pipelines, use the +[`CI_OPEN_MERGE_REQUESTS` variable](../variables/predefined_variables.md). + +The following example is for a project that runs branch and merge request pipelines only, +but does not run pipelines for any other case. It runs: + +- Branch pipelines when a merge request is not open for the branch. +- Merge request pipelines when a merge request is open for the branch. + +```yaml +workflow: + rules: + - if: '$CI_PIPELINE_SOURCE == "merge_request_event"' + - if: '$CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS' + when: never + - if: '$CI_COMMIT_BRANCH' +``` + +If the pipeline is triggered by: + +- A merge request, run a merge request pipeline. For example, a merge request pipeline + can be triggered by a push to a branch with an associated open merge request. +- A change to a branch, but a merge request is open for that branch, do not run a branch pipeline. +- A change to a branch, but without any open merge requests, run a branch pipeline. + +You can also add a rule to an existing `workflow` section to switch from branch pipelines +to merge request pipelines when a merge request is created. + +Add this rule to the top of the `workflow` section, followed by the other rules that +were already present: + +```yaml +workflow: + rules: + - if: $CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS && $CI_PIPELINE_SOURCE == "push" + when: never + - ... # Previously defined workflow rules here +``` + +[Triggered pipelines](../triggers/index.md) that run on a branch have a `$CI_COMMIT_BRANCH` +set and could be blocked by a similar rule. Triggered pipelines have a pipeline source +of `trigger` or `pipeline`, so `&& $CI_PIPELINE_SOURCE == "push"` ensures the rule +does not block triggered pipelines. + +### `include` + +> [Moved](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/42861) to GitLab Free in 11.4. + +Use `include` to include external YAML files in your CI/CD configuration. +You can break down one long `gitlab-ci.yml` file into multiple files to increase readability, +or reduce duplication of the same configuration in multiple places. + +You can also store template files in a central repository and `include` them in projects. + +`include` requires the external YAML file to have the extensions `.yml` or `.yaml`, +otherwise the external file is not included. + +You can't use [YAML anchors](#anchors) across different YAML files sourced by `include`. +You can only refer to anchors in the same file. To reuse configuration from different +YAML files, use [`!reference` tags](#reference-tags) or the [`extends` keyword](#extends). + +`include` supports the following inclusion methods: + +| Keyword | Method | +|:--------------------------------|:------------------------------------------------------------------| +| [`local`](#includelocal) | Include a file from the local project repository. | +| [`file`](#includefile) | Include a file from a different project repository. | +| [`remote`](#includeremote) | Include a file from a remote URL. Must be publicly accessible. | +| [`template`](#includetemplate) | Include templates that are provided by GitLab. | + +When the pipeline starts, the `.gitlab-ci.yml` file configuration included by all methods is evaluated. +The configuration is a snapshot in time and persists in the database. GitLab does not reflect any changes to +the referenced `.gitlab-ci.yml` file configuration until the next pipeline starts. + +The `include` files are: + +- Deep merged with those in the `.gitlab-ci.yml` file. +- Always evaluated first and merged with the content of the `.gitlab-ci.yml` file, + regardless of the position of the `include` keyword. + +NOTE: +Use merging to customize and override included CI/CD configurations with local +configurations. Local configurations in the `.gitlab-ci.yml` file override included configurations. + +#### Variables with `include` **(FREE SELF)** + +> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/284883) in GitLab 13.8. +> - [Feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/issues/294294) in GitLab 13.9. + +You can [use some predefined variables in `include` sections](../variables/where_variables_can_be_used.md#gitlab-ciyml-file) +in your `.gitlab-ci.yml` file: + +```yaml +include: + project: '$CI_PROJECT_PATH' + file: '.compliance-gitlab-ci.yml' +``` + +For an example of how you can include these predefined variables, and the variables' impact on CI/CD jobs, +see this [CI/CD variable demo](https://youtu.be/4XR8gw3Pkos). + +#### `include:local` + +Use `include:local` to include a file that is in the same repository as the `.gitlab-ci.yml` file. +Use a full path relative to the root directory (`/`). + +If you use `include:local`, make sure that both the `.gitlab-ci.yml` file and the local file +are on the same branch. + +You can't include local files through Git submodules paths. + +All [nested includes](#nested-includes) are executed in the scope of the same project, +so it's possible to use local, project, remote, or template includes. + +Example: + +```yaml +include: + - local: '/templates/.gitlab-ci-template.yml' +``` + +You can also use shorter syntax to define the path: + +```yaml +include: '.gitlab-ci-production.yml' +``` + +Use local includes instead of symbolic links. + +##### `include:local` with wildcard file paths + +> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/25921) in GitLab 13.11. +> - [Deployed behind a feature flag](../../user/feature_flags.md), disabled by default. +> - [Enabled by default](https://gitlab.com/gitlab-org/gitlab/-/issues/327315) in GitLab 13.12. +> - Enabled on GitLab.com. +> - Recommended for production use. +> - For GitLab self-managed instances, GitLab administrators can opt to disable it. **(CORE ONLY)** + +There can be +[risks when disabling released features](../../user/feature_flags.md#risks-when-disabling-released-features). +Refer to this feature's version history for more details. + +You can use wildcard paths (`*` and `**`) with `include:local`. + +Example: + +```yaml +include: 'configs/*.yml' +``` + +When the pipeline runs, GitLab: + +- Adds all `.yml` files in the `configs` directory into the pipeline configuration. +- Does not add `.yml` files in subfolders of the `configs` directory. To allow this, + add the following configuration: + + ```yaml + # This matches all `.yml` files in `configs` and any subfolder in it. + include: 'configs/**.yml' + + # This matches all `.yml` files only in subfolders of `configs`. + include: 'configs/**/*.yml' + ``` + +The wildcard file paths feature is under development but ready for production use. +It is deployed behind a feature flag that is **enabled by default**. +[GitLab administrators with access to the GitLab Rails console](../../administration/feature_flags.md) +can opt to disable it. + +To enable it: + +```ruby +Feature.enable(:ci_wildcard_file_paths) +``` + +To disable it: + +```ruby +Feature.disable(:ci_wildcard_file_paths) +``` + +#### `include:file` + +> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/53903) in GitLab 11.7. + +To include files from another private project on the same GitLab instance, +use `include:file`. You can use `include:file` in combination with `include:project` only. +Use a full path, relative to the root directory (`/`). + +For example: + +```yaml +include: + - project: 'my-group/my-project' + file: '/templates/.gitlab-ci-template.yml' +``` + +You can also specify a `ref`. If you do not specify a value, the ref defaults to the `HEAD` of the project: + +```yaml +include: + - project: 'my-group/my-project' + ref: main + file: '/templates/.gitlab-ci-template.yml' + + - project: 'my-group/my-project' + ref: v1.0.0 + file: '/templates/.gitlab-ci-template.yml' + + - project: 'my-group/my-project' + ref: 787123b47f14b552955ca2786bc9542ae66fee5b # Git SHA + file: '/templates/.gitlab-ci-template.yml' +``` + +All [nested includes](#nested-includes) are executed in the scope of the target project. +You can use local (relative to target project), project, remote, or template includes. + +##### Multiple files from a project + +> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/26793) in GitLab 13.6. +> - [Feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/issues/271560) in GitLab 13.8. + +You can include multiple files from the same project: + +```yaml +include: + - project: 'my-group/my-project' + ref: main + file: + - '/templates/.builds.yml' + - '/templates/.tests.yml' +``` + +#### `include:remote` + +Use `include:remote` with a full URL to include a file from a different location. +The remote file must be publicly accessible by an HTTP/HTTPS `GET` request, because +authentication in the remote URL is not supported. For example: + +```yaml +include: + - remote: 'https://gitlab.com/example-project/-/raw/main/.gitlab-ci.yml' +``` + +All [nested includes](#nested-includes) execute without context as a public user, +so you can only `include` public projects or templates. + +#### `include:template` + +> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/53445) in GitLab 11.7. + +Use `include:template` to include `.gitlab-ci.yml` templates that are +[shipped with GitLab](https://gitlab.com/gitlab-org/gitlab/-/tree/master/lib/gitlab/ci/templates). + +For example: + +```yaml +# File sourced from the GitLab template collection +include: + - template: Auto-DevOps.gitlab-ci.yml +``` + +Multiple `include:template` files: + +```yaml +include: + - template: Android-Fastlane.gitlab-ci.yml + - template: Auto-DevOps.gitlab-ci.yml +``` + +All [nested includes](#nested-includes) are executed only with the permission of the user, +so it's possible to use project, remote or template includes. + +#### Nested includes + +> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/56836) in GitLab 11.9. + +Use nested includes to compose a set of includes. + +You can have up to 100 includes, but you can't have duplicate includes. + +In [GitLab 12.4](https://gitlab.com/gitlab-org/gitlab/-/issues/28212) and later, the time limit +to resolve all files is 30 seconds. + +#### Additional `includes` examples + +View [additional `includes` examples](includes.md). + +## Keyword details + +The following topics explain how to use keywords to configure CI/CD pipelines. + +### `image` + +Use `image` to specify [a Docker image](../docker/using_docker_images.md#what-is-an-image) to use for the job. + +For: + +- Usage examples, see [Define `image` in the `.gitlab-ci.yml` file](../docker/using_docker_images.md#define-image-in-the-gitlab-ciyml-file). +- Detailed usage information, refer to [Docker integration](../docker/index.md) documentation. + +#### `image:name` + +An [extended Docker configuration option](../docker/using_docker_images.md#extended-docker-configuration-options). + +For more information, see [Available settings for `image`](../docker/using_docker_images.md#available-settings-for-image). + +#### `image:entrypoint` + +An [extended Docker configuration option](../docker/using_docker_images.md#extended-docker-configuration-options). + +For more information, see [Available settings for `image`](../docker/using_docker_images.md#available-settings-for-image). + +#### `services` + +Use `services` to specify a [service Docker image](../services/index.md), linked to a base image specified in [`image`](#image). + +For: + +- Usage examples, see [Define `services` in the `.gitlab-ci.yml` file](../services/index.md#define-services-in-the-gitlab-ciyml-file). +- Detailed usage information, refer to [Docker integration](../docker/index.md) documentation. +- Example services, see [GitLab CI/CD Services](../services/index.md). + +##### `services:name` + +An [extended Docker configuration option](../docker/using_docker_images.md#extended-docker-configuration-options). + +For more information, see [Available settings for `services`](../services/index.md#available-settings-for-services). + +##### `services:alias` + +An [extended Docker configuration option](../docker/using_docker_images.md#extended-docker-configuration-options). + +For more information, see [Available settings for `services`](../services/index.md#available-settings-for-services). + +##### `services:entrypoint` + +An [extended Docker configuration option](../docker/using_docker_images.md#extended-docker-configuration-options). + +For more information, see [Available settings for `services`](../services/index.md#available-settings-for-services). + +##### `services:command` + +An [extended Docker configuration option](../docker/using_docker_images.md#extended-docker-configuration-options). + +For more information, see [Available settings for `services`](../services/index.md#available-settings-for-services). + +### `script` + +Use `script` to specify a shell script for the runner to execute. + +All jobs except [trigger jobs](#trigger) require a `script` keyword. + +For example: + +```yaml +job: + script: "bundle exec rspec" +``` + +You can use [YAML anchors with `script`](#yaml-anchors-for-scripts). + +The `script` keyword can also contain several commands in an array: + +```yaml +job: + script: + - uname -a + - bundle exec rspec +``` + +Sometimes, `script` commands must be wrapped in single or double quotes. +For example, commands that contain a colon (`:`) must be wrapped in single quotes (`'`). +The YAML parser needs to interpret the text as a string rather than +a "key: value" pair. + +For example, this script uses a colon: + +```yaml +job: + script: + - curl --request POST --header 'Content-Type: application/json' "https://gitlab/api/v4/projects" +``` + +To be considered valid YAML, you must wrap the entire command in single quotes. If +the command already uses single quotes, you should change them to double quotes (`"`) +if possible: + +```yaml +job: + script: + - 'curl --request POST --header "Content-Type: application/json" "https://gitlab/api/v4/projects"' +``` + +You can verify the syntax is valid with the [CI Lint](../lint.md) tool. + +Be careful when using these characters as well: + +- `{`, `}`, `[`, `]`, `,`, `&`, `*`, `#`, `?`, `|`, `-`, `<`, `>`, `=`, `!`, `%`, `@`, `` ` ``. + +If any of the script commands return an exit code other than zero, the job +fails and further commands are not executed. Store the exit code in a variable to +avoid this behavior: + +```yaml +job: + script: + - false || exit_code=$? + - if [ $exit_code -ne 0 ]; then echo "Previous command failed"; fi; +``` + +#### `before_script` + +Use `before_script` to define an array of commands that should run before each job, +but after [artifacts](#artifacts) are restored. + +Scripts you specify in `before_script` are concatenated with any scripts you specify +in the main [`script`](#script). The combine scripts execute together in a single shell. + +You can overwrite a globally-defined `before_script` if you define it in a job: + +```yaml +default: + before_script: + - echo "Execute this script in all jobs that don't already have a before_script section." + +job1: + script: + - echo "This script executes after the global before_script." + +job: + before_script: + - echo "Execute this script instead of the global before_script." + script: + - echo "This script executes after the job's `before_script`" +``` + +You can use [YAML anchors with `before_script`](#yaml-anchors-for-scripts). + +#### `after_script` + +Use `after_script` to define an array of commands that run after each job, +including failed jobs. + +If a job times out or is cancelled, the `after_script` commands do not execute. +An [issue](https://gitlab.com/gitlab-org/gitlab/-/issues/15603) exists to support +executing `after_script` commands for timed-out or cancelled jobs. + +Scripts you specify in `after_script` execute in a new shell, separate from any +`before_script` or `script` scripts. As a result, they: + +- Have a current working directory set back to the default. +- Have no access to changes done by scripts defined in `before_script` or `script`, including: + - Command aliases and variables exported in `script` scripts. + - Changes outside of the working tree (depending on the runner executor), like + software installed by a `before_script` or `script` script. +- Have a separate timeout, which is hard coded to 5 minutes. See the + [related issue](https://gitlab.com/gitlab-org/gitlab-runner/-/issues/2716) for details. +- Don't affect the job's exit code. If the `script` section succeeds and the + `after_script` times out or fails, the job exits with code `0` (`Job Succeeded`). + +```yaml +default: + after_script: + - echo "Execute this script in all jobs that don't already have an after_script section." + +job1: + script: + - echo "This script executes first. When it completes, the global after_script executes." + +job: + script: + - echo "This script executes first. When it completes, the job's `after_script` executes." + after_script: + - echo "Execute this script instead of the global after_script." +``` + +You can use [YAML anchors with `after_script`](#yaml-anchors-for-scripts). + +#### Script syntax + +You can use syntax in [`script`](#script) sections to: + +- [Split long commands](script.md#split-long-commands) into multiline commands. +- [Use color codes](script.md#add-color-codes-to-script-output) to make job logs easier to review. +- [Create custom collapsible sections](../jobs/index.md#custom-collapsible-sections) + to simplify job log output. + +### `stage` + +Use `stage` to define which stage a job runs in. Jobs in the same +`stage` can execute in parallel (subject to [certain conditions](#use-your-own-runners)). + +Jobs without a `stage` entry use the `test` stage by default. If you do not define +[`stages`](#stages) in the pipeline, you can use the 5 default stages, which execute in +this order: + +- [`.pre`](#pre-and-post) +- `build` +- `test` +- `deploy` +- [`.post`](#pre-and-post) +For example: + +```yaml +stages: + - build + - test + - deploy + +job 0: + stage: .pre + script: make something useful before build stage + +job 1: + stage: build + script: make build dependencies + +job 2: + stage: build + script: make build artifacts + +job 3: + stage: test + script: make test + +job 4: + stage: deploy + script: make deploy + +job 5: + stage: .post + script: make something useful at the end of pipeline +``` + +#### Use your own runners + +When you use your own runners, each runner runs only one job at a time by default. +Jobs can run in parallel if they run on different runners. + +If you have only one runner, jobs can run in parallel if the runner's +[`concurrent` setting](https://docs.gitlab.com/runner/configuration/advanced-configuration.html#the-global-section) +is greater than `1`. + +#### `.pre` and `.post` + +> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/31441) in GitLab 12.4. + +Use `pre` and `post` for jobs that need to run first or last in a pipeline. + +- `.pre` is guaranteed to always be the first stage in a pipeline. +- `.post` is guaranteed to always be the last stage in a pipeline. + +User-defined stages are executed after `.pre` and before `.post`. + +You must have a job in at least one stage other than `.pre` or `.post`. + +You can't change the order of `.pre` and `.post`, even if you define them out of order in the `.gitlab-ci.yml` file. +For example, the following configurations are equivalent: + +```yaml +stages: + - .pre + - a + - b + - .post +``` + +```yaml +stages: + - a + - .pre + - b + - .post +``` + +```yaml +stages: + - a + - b +``` + +### `extends` + +> Introduced in GitLab 11.3. + +Use `extends` to reuse configuration sections. It's an alternative to [YAML anchors](#anchors) +and is a little more flexible and readable. You can use `extends` to reuse configuration +from [included configuration files](#use-extends-and-include-together). + +In the following example, the `rspec` job uses the configuration from the `.tests` template job. +GitLab: + +- Performs a reverse deep merge based on the keys. +- Merges the `.tests` content with the `rspec` job. +- Doesn't merge the values of the keys. + +```yaml +.tests: + script: rake test + stage: test + only: + refs: + - branches + +rspec: + extends: .tests + script: rake rspec + only: + variables: + - $RSPEC +``` + +The result is this `rspec` job: + +```yaml +rspec: + script: rake rspec + stage: test + only: + refs: + - branches + variables: + - $RSPEC +``` + +`.tests` in this example is a [hidden job](#hide-jobs), but it's +possible to extend configuration from regular jobs as well. + +`extends` supports multi-level inheritance. You should avoid using more than three levels, +but you can use as many as eleven. The following example has two levels of inheritance: + +```yaml +.tests: + rules: + - if: $CI_PIPELINE_SOURCE == "push" + +.rspec: + extends: .tests + script: rake rspec + +rspec 1: + variables: + RSPEC_SUITE: '1' + extends: .rspec + +rspec 2: + variables: + RSPEC_SUITE: '2' + extends: .rspec + +spinach: + extends: .tests + script: rake spinach +``` + +In GitLab 12.0 and later, it's also possible to use multiple parents for +`extends`. + +#### Merge details + +You can use `extends` to merge hashes but not arrays. +The algorithm used for merge is "closest scope wins," so +keys from the last member always override anything defined on other +levels. For example: + +```yaml +.only-important: + variables: + URL: "http://my-url.internal" + IMPORTANT_VAR: "the details" + rules: + - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH + - if: $CI_COMMIT_BRANCH == "stable" + tags: + - production + script: + - echo "Hello world!" + +.in-docker: + variables: + URL: "http://docker-url.internal" + tags: + - docker + image: alpine + +rspec: + variables: + GITLAB: "is-awesome" + extends: + - .only-important + - .in-docker + script: + - rake rspec +``` + +The result is this `rspec` job: + +```yaml +rspec: + variables: + URL: "http://docker-url.internal" + IMPORTANT_VAR: "the details" + GITLAB: "is-awesome" + rules: + - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH + - if: $CI_COMMIT_BRANCH == "stable" + tags: + - docker + image: alpine + script: + - rake rspec +``` + +In this example: + +- The `variables` sections merge, but `URL: "http://docker-url.internal"` overwrites `URL: "http://my-url.internal"`. +- `tags: ['docker']` overwrites `tags: ['production']`. +- `script` does not merge, but `script: ['rake rspec']` overwrites + `script: ['echo "Hello world!"']`. You can use [YAML anchors](#anchors) to merge arrays. + +#### Use `extends` and `include` together + +To reuse configuration from different configuration files, +combine `extends` and [`include`](#include). + +In the following example, a `script` is defined in the `included.yml` file. +Then, in the `.gitlab-ci.yml` file, `extends` refers +to the contents of the `script`: + +- `included.yml`: + + ```yaml + .template: + script: + - echo Hello! + ``` + +- `.gitlab-ci.yml`: + + ```yaml + include: included.yml + + useTemplate: + image: alpine + extends: .template + ``` + +### `rules` + +> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/27863) in GitLab 12.3. + +Use `rules` to include or exclude jobs in pipelines. + +Rules are evaluated *in order* until the first match. When a match is found, the job +is either included or excluded from the pipeline, depending on the configuration. + +`rules` replaces [`only/except`](#only--except) and they can't be used together +in the same job. If you configure one job to use both keywords, the GitLab returns +a `key may not be used with rules` error. + +`rules` accepts an array of rules defined with: + +- `if` +- `changes` +- `exists` +- `allow_failure` +- `variables` +- `when` + +You can combine multiple keywords together for [complex rules](../jobs/job_control.md#complex-rules). + +The job is added to the pipeline: + +- If an `if`, `changes`, or `exists` rule matches and also has `when: on_success` (default), + `when: delayed`, or `when: always`. +- If a rule is reached that is only `when: on_success`, `when: delayed`, or `when: always`. + +The job is not added to the pipeline: + +- If no rules match. +- If a rule matches and has `when: never`. + +#### `rules:if` + +Use `rules:if` clauses to specify when to add a job to a pipeline: + +- If an `if` statement is true, add the job to the pipeline. +- If an `if` statement is true, but it's combined with `when: never`, do not add the job to the pipeline. +- If no `if` statements are true, do not add the job to the pipeline. + +`if:` clauses are evaluated based on the values of [predefined CI/CD variables](../variables/predefined_variables.md) +or [custom CI/CD variables](../variables/index.md#custom-cicd-variables). + +**Keyword type**: Job-specific and pipeline-specific. You can use it as part of a job +to configure the job behavior, or with [`workflow`](#workflow) to configure the pipeline behavior. + +**Possible inputs**: A [CI/CD variable expression](../jobs/job_control.md#cicd-variable-expressions). + +**Example of `rules:if`**: + +```yaml +job: + script: echo "Hello, Rules!" + rules: + - if: '$CI_MERGE_REQUEST_SOURCE_BRANCH_NAME =~ /^feature/ && $CI_MERGE_REQUEST_TARGET_BRANCH_NAME != $CI_DEFAULT_BRANCH' + when: never + - if: '$CI_MERGE_REQUEST_SOURCE_BRANCH_NAME =~ /^feature/' + when: manual + allow_failure: true + - if: '$CI_MERGE_REQUEST_SOURCE_BRANCH_NAME' +``` + +**Additional details**: + +- If a rule matches and has no `when` defined, the rule uses the `when` + defined for the job, which defaults to `on_success` if not defined. +- You can define `when` once per rule, or once at the job-level, which applies to + all rules. You can't mix `when` at the job-level with `when` in rules. +- Unlike variables in [`script`](../variables/index.md#use-cicd-variables-in-job-scripts) + sections, variables in rules expressions are always formatted as `$VARIABLE`. + +**Related topics**: + +- [Common `if` expressions for `rules`](../jobs/job_control.md#common-if-clauses-for-rules). +- [Avoid duplicate pipelines](../jobs/job_control.md#avoid-duplicate-pipelines). + +#### `rules:changes` + +Use `rules:changes` to specify when to add a job to a pipeline by checking for changes +to specific files. + +WARNING: +You should use `rules: changes` only with **branch pipelines** or **merge request pipelines**. +You can use `rules: changes` with other pipeline types, but `rules: changes` always +evaluates to true when there is no Git `push` event. Tag pipelines, scheduled pipelines, +and so on do **not** have a Git `push` event associated with them. A `rules: changes` job +is **always** added to those pipelines if there is no `if:` that limits the job to +branch or merge request pipelines. + +**Keyword type**: Job keyword. You can use it only as part of a job. + +**Possible inputs**: An array of file paths. In GitLab 13.6 and later, +[file paths can include variables](../jobs/job_control.md#variables-in-ruleschanges). + +**Example of `rules:changes`**: + +```yaml +docker build: + script: docker build -t my-image:$CI_COMMIT_REF_SLUG . + rules: + - if: '$CI_PIPELINE_SOURCE == "merge_request_event"' + changes: + - Dockerfile + when: manual + allow_failure: true +``` + +- If the pipeline is a merge request pipeline, check `Dockerfile` for changes. +- If `Dockerfile` has changed, add the job to the pipeline as a manual job, and the pipeline + continues running even if the job is not triggered (`allow_failure: true`). +- If `Dockerfile` has not changed, do not add job to any pipeline (same as `when: never`). + +**Additional details**: + +- `rules: changes` works the same way as [`only: changes` and `except: changes`](#onlychanges--exceptchanges). +- You can use `when: never` to implement a rule similar to [`except:changes`](#onlychanges--exceptchanges). + +#### `rules:exists` + +> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/24021) in GitLab 12.4. + +Use `exists` to run a job when certain files exist in the repository. + +**Keyword type**: Job keyword. You can use it only as part of a job. + +**Possible inputs**: An array of file paths. Paths are relative to the project directory (`$CI_PROJECT_DIR`) +and can't directly link outside it. File paths can use glob patterns. + +**Example of `rules:exists`**: + +```yaml +job: + script: docker build -t my-image:$CI_COMMIT_REF_SLUG . + rules: + - exists: + - Dockerfile +``` + +`job` runs if a `Dockerfile` exists anywhere in the repository. + +**Additional details**: + +- Glob patterns are interpreted with Ruby [`File.fnmatch`](https://docs.ruby-lang.org/en/2.7.0/File.html#method-c-fnmatch) + with the flags `File::FNM_PATHNAME | File::FNM_DOTMATCH | File::FNM_EXTGLOB`. +- For performance reasons, GitLab matches a maximum of 10,000 `exists` patterns or + file paths. After the 10,000th check, rules with patterned globs always match. + In other words, the `exists` rule always assumes a match in projects with more + than 10,000 files. + +#### `rules:allow_failure` + +> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/30235) in GitLab 12.8. + +Use [`allow_failure: true`](#allow_failure) in `rules:` to allow a job to fail +without stopping the pipeline. + +You can also use `allow_failure: true` with a manual job. The pipeline continues +running without waiting for the result of the manual job. `allow_failure: false` +combined with `when: manual` in rules causes the pipeline to wait for the manual +job to run before continuing. + +**Keyword type**: Job keyword. You can use it only as part of a job. + +**Possible inputs**: `true` or `false`. Defaults to `false` if not defined. + +**Example of `rules:allow_failure`**: + +```yaml +job: + script: echo "Hello, Rules!" + rules: + - if: '$CI_MERGE_REQUEST_TARGET_BRANCH_NAME == $CI_DEFAULT_BRANCH' + when: manual + allow_failure: true +``` + +If the rule matches, then the job is a manual job with `allow_failure: true`. + +**Additional details**: + +- The rule-level `rules:allow_failure` overrides the job-level [`allow_failure`](#allow_failure), + and only applies when the specific rule triggers the job. + +#### `rules:variables` + +> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/209864) in GitLab 13.7. +> - [Feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/issues/289803) in GitLab 13.10. + +Use [`variables`](#variables) in `rules:` to define variables for specific conditions. + +**Keyword type**: Job-specific. You can use it only as part of a job. + +**Possible inputs**: A hash of variables in the format `VARIABLE-NAME: value`. + +**Example of `rules:variables`**: + +```yaml +job: + variables: + DEPLOY_VARIABLE: "default-deploy" + rules: + - if: $CI_COMMIT_REF_NAME == $CI_DEFAULT_BRANCH + variables: # Override DEPLOY_VARIABLE defined + DEPLOY_VARIABLE: "deploy-production" # at the job level. + - if: $CI_COMMIT_REF_NAME =~ /feature/ + variables: + IS_A_FEATURE: "true" # Define a new variable. + script: + - echo "Run script with $DEPLOY_VARIABLE as an argument" + - echo "Run another script if $IS_A_FEATURE exists" +``` + +### `only` / `except` + +NOTE: +`only` and `except` are not being actively developed. [`rules`](#rules) is the preferred +keyword to control when to add jobs to pipelines. + +You can use `only` and `except` to control when to add jobs to pipelines. + +- Use `only` to define when a job runs. +- Use `except` to define when a job **does not** run. + +Four keywords can be used with `only` and `except`: + +- [`refs`](#onlyrefs--exceptrefs) +- [`variables`](#onlyvariables--exceptvariables) +- [`changes`](#onlychanges--exceptchanges) +- [`kubernetes`](#onlykubernetes--exceptkubernetes) + +See [specify when jobs run with `only` and `except`](../jobs/job_control.md#specify-when-jobs-run-with-only-and-except) +for more details and examples. + +#### `only:refs` / `except:refs` + +Use the `only:refs` and `except:refs` keywords to control when to add jobs to a +pipeline based on branch names or pipeline types. + +**Keyword type**: Job keyword. You can use it only as part of a job. + +**Possible inputs**: An array including any number of: + +- Branch names, for example `main` or `my-feature-branch`. +- [Regular expressions](../jobs/job_control.md#only--except-regex-syntax) + that match against branch names, for example `/^feature-.*/`. +- The following keywords: + + | **Value** | **Description** | + | -------------------------|-----------------| + | `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/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). | + | `pipelines` | For [multi-project pipelines](../multi_project_pipelines.md) created by [using the API with `CI_JOB_TOKEN`](../multi_project_pipelines.md#create-multi-project-pipelines-by-using-the-api), or the [`trigger`](#trigger) keyword. | + | `pushes` | For pipelines triggered by a `git push` event, including for branches and tags. | + | `schedules` | For [scheduled pipelines](../pipelines/schedules.md). | + | `tags` | When the Git reference for a pipeline is a tag. | + | `triggers` | For pipelines created by using a [trigger token](../triggers/index.md#trigger-token). | + | `web` | For pipelines created by using **Run pipeline** button in the GitLab UI, from the project's **CI/CD > Pipelines** section. | + +**Example of `only:refs` and `except:refs`**: + +```yaml +job1: + script: echo + only: + - main + - /^issue-.*$/ + - merge_requests + +job2: + script: echo + except: + - main + - /^stable-branch.*$/ + - schedules +``` + +**Additional details:** + +- Scheduled pipelines run on specific branches, so jobs configured with `only: branches` + run on scheduled pipelines too. Add `except: schedules` to prevent jobs with `only: branches` + from running on scheduled pipelines. +- `only` or `except` used without any other keywords are equivalent to `only: refs` + or `except: refs`. For example, the following two jobs configurations have the same + behavior: + + ```yaml + job1: + script: echo + only: + - branches + + job2: + script: echo + only: + refs: + - branches + ``` + +- If a job does not use `only`, `except`, or [`rules`](#rules), then `only` is set to `branches` + and `tags` by default. + + For example, `job1` and `job2` are equivalent: + + ```yaml + job1: + script: echo 'test' + + job2: + script: echo 'test' + only: + - branches + - tags + ``` + +#### `only:variables` / `except:variables` + +Use the `only:variables` or `except:variables` keywords to control when to add jobs +to a pipeline, based on the status of [CI/CD variables](../variables/index.md). + +**Keyword type**: Job keyword. You can use it only as part of a job. + +**Possible inputs**: An array of [CI/CD variable expressions](../jobs/job_control.md#cicd-variable-expressions). + +**Example of `only:variables`**: + +```yaml +deploy: + script: cap staging deploy + only: + variables: + - $RELEASE == "staging" + - $STAGING +``` + +**Related topics**: + +- [`only:variables` and `except:variables` examples](../jobs/job_control.md#only-variables--except-variables-examples). + +#### `only:changes` / `except:changes` + +> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/19232) in GitLab 11.4. + +Use the `changes` keyword with `only` to run a job, or with `except` to skip a job, +when a Git push event modifies a file. + +Use `changes` in pipelines with the following refs: + +- `branches` +- `external_pull_requests` +- `merge_requests` (see additional details about [using `only:changes` with pipelines for merge requests](../jobs/job_control.md#use-onlychanges-with-pipelines-for-merge-requests)) + +**Keyword type**: Job keyword. You can use it only as part of a job. + +**Possible inputs**: An array including any number of: + +- Paths to files. +- Wildcard paths for single directories, for example `path/to/directory/*`, or a directory + and all its subdirectories, for example `path/to/directory/**/*`. +- Wildcard ([glob](https://en.wikipedia.org/wiki/Glob_(programming))) paths for all + files with the same extension or multiple extensions, for example `*.md` or `path/to/directory/*.{rb,py,sh}`. +- Wildcard paths to files in the root directory, or all directories, wrapped in double quotes. + For example `"*.json"` or `"**/*.json"`. + +**Example of `only:changes`**: + +```yaml +docker build: + script: docker build -t my-image:$CI_COMMIT_REF_SLUG . + only: + refs: + - branches + changes: + - Dockerfile + - docker/scripts/* + - dockerfiles/**/* + - more_scripts/*.{rb,py,sh} +``` + +**Additional details**: + +- If you use refs other than `branches`, `external_pull_requests`, or `merge_requests`, + `changes` can't determine if a given file is new or old and always returns `true`. +- If you use `only: changes` with other refs, jobs ignore the changes and always run. +- If you use `except: changes` with other refs, jobs ignore the changes and never run. + +**Related topics**: + +- [`only: changes` and `except: changes` examples](../jobs/job_control.md#onlychanges--exceptchanges-examples). +- If you use `changes` with [only allow merge requests to be merged if the pipeline succeeds](../../user/project/merge_requests/merge_when_pipeline_succeeds.md#only-allow-merge-requests-to-be-merged-if-the-pipeline-succeeds), + you should [also use `only:merge_requests`](../jobs/job_control.md#use-onlychanges-with-pipelines-for-merge-requests). +- Use `changes` with [new branches or tags *without* pipelines for merge requests](../jobs/job_control.md#use-onlychanges-without-pipelines-for-merge-requests). +- Use `changes` with [scheduled pipelines](../jobs/job_control.md#use-onlychanges-with-scheduled-pipelines). + +#### `only:kubernetes` / `except:kubernetes` + +Use `only:kubernetes` or `except:kubernetes` to control if jobs are added to the pipeline +when the Kubernetes service is active in the project. + +**Keyword type**: Job-specific. You can use it only as part of a job. + +**Possible inputs**: The `kubernetes` strategy accepts only the `active` keyword. + +**Example of `only:kubernetes`**: + +```yaml +deploy: + only: + kubernetes: active +``` + +In this example, the `deploy` job runs only when the Kubernetes service is active +in the project. + +### `needs` + +> - [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/47063) in GitLab 12.2. +> - In GitLab 12.3, maximum number of jobs in `needs` array raised from five to 50. +> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/30631) in GitLab 12.8, `needs: []` lets jobs start immediately. + +Use `needs:` to execute jobs out-of-order. Relationships between jobs +that use `needs` can be visualized as a [directed acyclic graph](../directed_acyclic_graph/index.md). + +You can ignore stage ordering and run some jobs without waiting for others to complete. +Jobs in multiple stages can run concurrently. + +The following example creates four paths of execution: + +- Linter: the `lint` job runs immediately without waiting for the `build` stage + to complete because it has no needs (`needs: []`). +- Linux path: the `linux:rspec` and `linux:rubocop` jobs runs as soon as the `linux:build` + job finishes without waiting for `mac:build` to finish. +- macOS path: the `mac:rspec` and `mac:rubocop` jobs runs as soon as the `mac:build` + job finishes, without waiting for `linux:build` to finish. +- The `production` job runs as soon as all previous jobs finish; in this case: + `linux:build`, `linux:rspec`, `linux:rubocop`, `mac:build`, `mac:rspec`, `mac:rubocop`. + +```yaml +linux:build: + stage: build + script: echo "Building linux..." + +mac:build: + stage: build + script: echo "Building mac..." + +lint: + stage: test + needs: [] + script: echo "Linting..." + +linux:rspec: + stage: test + needs: ["linux:build"] + script: echo "Running rspec on linux..." + +linux:rubocop: + stage: test + needs: ["linux:build"] + script: echo "Running rubocop on linux..." + +mac:rspec: + stage: test + needs: ["mac:build"] + script: echo "Running rspec on mac..." + +mac:rubocop: + stage: test + needs: ["mac:build"] + script: echo "Running rubocop on mac..." + +production: + stage: deploy + script: echo "Running production..." +``` + +#### Requirements and limitations + +- In GitLab 13.9 and older, if `needs:` refers to a job that might not be added to + a pipeline because of `only`, `except`, or `rules`, the pipeline might fail to create. +- The maximum number of jobs that a single job can need in the `needs:` array is limited: + - For GitLab.com, the limit is 50. For more information, see our + [infrastructure issue](https://gitlab.com/gitlab-com/gl-infra/infrastructure/-/issues/7541). + - For self-managed instances, the limit is: 50. This limit [can be changed](#changing-the-needs-job-limit). +- If `needs:` refers to a job that uses the [`parallel`](#parallel) keyword, + it depends on all jobs created in parallel, not just one job. It also downloads + artifacts from all the parallel jobs by default. If the artifacts have the same + name, they overwrite each other and only the last one downloaded is saved. +- `needs:` is similar to `dependencies:` in that it must use jobs from prior stages, + meaning it's impossible to create circular dependencies. Depending on jobs in the + current stage is not possible either, but support [is planned](https://gitlab.com/gitlab-org/gitlab/-/issues/30632). +- Stages must be explicitly defined for all jobs + that have the keyword `needs:` or are referred to by one. + +##### Changing the `needs:` job limit **(FREE SELF)** + +The maximum number of jobs that can be defined in `needs:` defaults to 50. + +A GitLab administrator with [access to the GitLab Rails console](../../administration/feature_flags.md) +can choose a custom limit. For example, to set the limit to 100: + +```ruby +Plan.default.actual_limits.update!(ci_needs_size_limit: 100) +``` + +To disable directed acyclic graphs (DAG), set the limit to `0`. + +#### Artifact downloads with `needs` + +> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/14311) in GitLab v12.6. + +When a job uses `needs`, it no longer downloads all artifacts from previous stages +by default, because jobs with `needs` can start before earlier stages complete. With +`needs` you can only download artifacts from the jobs listed in the `needs:` configuration. + +Use `artifacts: true` (default) or `artifacts: false` to control when artifacts are +downloaded in jobs that use `needs`. + +In the following example, the `rspec` job downloads the `build_job` artifacts, but the +`rubocop` job does not: + +```yaml +build_job: + stage: build + artifacts: + paths: + - binaries/ + +rspec: + stage: test + needs: + - job: build_job + artifacts: true + +rubocop: + stage: test + needs: + - job: build_job + artifacts: false +``` + +In the following example, the `rspec` job downloads the artifacts from all three `build_jobs`. +`artifacts` is: + +- Set to true for `build_job_1`. +- Defaults to true for both `build_job_2` and `build_job_3`. + +```yaml +rspec: + needs: + - job: build_job_1 + artifacts: true + - job: build_job_2 + - build_job_3 +``` + +In GitLab 12.6 and later, you can't combine the [`dependencies`](#dependencies) keyword +with `needs`. + +#### Cross project artifact downloads with `needs` **(PREMIUM)** + +> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/14311) in GitLab v12.7. + +Use `needs` to download artifacts from up to five jobs in pipelines: + +- [On other refs in the same project](#artifact-downloads-between-pipelines-in-the-same-project). +- In different projects, groups and namespaces. + +```yaml +build_job: + stage: build + script: + - ls -lhR + needs: + - project: namespace/group/project-name + job: build-1 + ref: main + artifacts: true +``` + +`build_job` downloads the artifacts from the latest successful `build-1` job +on the `main` branch in the `group/project-name` project. If the project is in the +same group or namespace, you can omit them from the `project:` keyword. For example, +`project: group/project-name` or `project: project-name`. + +The user running the pipeline must have at least `reporter` access to the group or project, or the group/project must have public visibility. + +##### Artifact downloads between pipelines in the same project + +Use `needs` to download artifacts from different pipelines in the current project. +Set the `project` keyword as the current project's name, and specify a ref. + +In the following example, `build_job` downloads the artifacts for the latest successful +`build-1` job with the `other-ref` ref: + +```yaml +build_job: + stage: build + script: + - ls -lhR + needs: + - project: group/same-project-name + job: build-1 + ref: other-ref + artifacts: true +``` + +CI/CD variable support for `project:`, `job:`, and `ref` was [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/202093) +in GitLab 13.3. [Feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/issues/235761) in GitLab 13.4. + +For example: + +```yaml +build_job: + stage: build + script: + - ls -lhR + needs: + - project: $CI_PROJECT_PATH + job: $DEPENDENCY_JOB_NAME + ref: $ARTIFACTS_DOWNLOAD_REF + artifacts: true +``` + +You can't download artifacts from jobs that run in [`parallel:`](#parallel). + +To download artifacts between [parent-child pipelines](../parent_child_pipelines.md), +use [`needs:pipeline`](#artifact-downloads-to-child-pipelines). + +You should not download artifacts from the same ref as a running pipeline. Concurrent +pipelines running on the same ref could override the artifacts. + +##### Artifact downloads to child pipelines + +> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/255983) in GitLab v13.7. + +A [child pipeline](../parent_child_pipelines.md) can download artifacts from a job in +its parent pipeline or another child pipeline in the same parent-child pipeline hierarchy. + +For example, with the following parent pipeline that has a job that creates some artifacts: + +```yaml +create-artifact: + stage: build + script: echo 'sample artifact' > artifact.txt + artifacts: + paths: [artifact.txt] + +child-pipeline: + stage: test + trigger: + include: child.yml + strategy: depend + variables: + PARENT_PIPELINE_ID: $CI_PIPELINE_ID +``` + +A job in the child pipeline can download artifacts from the `create-artifact` job in +the parent pipeline: + +```yaml +use-artifact: + script: cat artifact.txt + needs: + - pipeline: $PARENT_PIPELINE_ID + job: create-artifact +``` + +The `pipeline` attribute accepts a pipeline ID and it must be a pipeline present +in the same parent-child pipeline hierarchy of the given pipeline. + +The `pipeline` attribute does not accept the current pipeline ID (`$CI_PIPELINE_ID`). +To download artifacts from a job in the current pipeline, use the basic form of [`needs`](#artifact-downloads-with-needs). + +#### Optional `needs` + +> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/30680) in GitLab 13.10. +> - [Feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/issues/323891) in GitLab 14.0. + +To need a job that sometimes does not exist in the pipeline, add `optional: true` +to the `needs` configuration. If not defined, `optional: false` is the default. + +Jobs that use [`rules`](#rules), [`only`, or `except`](#only--except), might +not always exist in a pipeline. When the pipeline starts, it checks the `needs` +relationships before running. Without `optional: true`, needs relationships that +point to a job that does not exist stops the pipeline from starting and causes a pipeline +error similar to: + +- `'job1' job needs 'job2' job, but it was not added to the pipeline` + +In this example: + +- When the branch is the default branch, the `build` job exists in the pipeline, and the `rspec` + job waits for it to complete before starting. +- When the branch is not the default branch, the `build` job does not exist in the pipeline. + The `rspec` job runs immediately (similar to `needs: []`) because its `needs` + relationship to the `build` job is optional. + +```yaml +build: + stage: build + rules: + - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH + +rspec: + stage: test + needs: + - job: build + optional: true +``` + +### `tags` + +Use `tags` to select a specific runner from the list of all runners that are +available for the project. + +When you register a runner, you can specify the runner's tags, for +example `ruby`, `postgres`, `development`. + +In the following example, the job is run by a runner that +has both `ruby` and `postgres` tags defined. + +```yaml +job: + tags: + - ruby + - postgres +``` + +You can use tags to run different jobs on different platforms. For +example, if you have an OS X runner with tag `osx` and a Windows runner with tag +`windows`, you can run a job on each platform: + +```yaml +windows job: + stage: + - build + tags: + - windows + script: + - echo Hello, %USERNAME%! + +osx job: + stage: + - build + tags: + - osx + script: + - echo "Hello, $USER!" +``` + +### `allow_failure` + +Use `allow_failure` when you want to let a job fail without impacting the rest of the CI +suite. The default value is `false`, except for [manual](#whenmanual) jobs that use +the `when: manual` syntax. + +In jobs that use [`rules:`](#rules), all jobs default to `allow_failure: false`, +*including* `when: manual` jobs. + +When `allow_failure` is set to `true` and the job fails, the job shows an orange warning in the UI. +However, the logical flow of the pipeline considers the job a +success/passed, and is not blocked. + +Assuming all other jobs are successful, the job's stage and its pipeline +show the same orange warning. However, the associated commit is marked as +"passed", without warnings. + +In the following example, `job1` and `job2` run in parallel. If `job1` +fails, it doesn't stop the next stage from running, because it's marked with +`allow_failure: true`: + +```yaml +job1: + stage: test + script: + - execute_script_that_will_fail + allow_failure: true + +job2: + stage: test + script: + - execute_script_that_will_succeed + +job3: + stage: deploy + script: + - deploy_to_staging +``` + +#### `allow_failure:exit_codes` + +> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/273157) in GitLab 13.8. +> - [Feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/issues/292024) in GitLab 13.9. + +Use `allow_failure:exit_codes` to dynamically control if a job should be allowed +to fail. You can list which exit codes are not considered failures. The job fails +for any other exit code: + +```yaml +test_job_1: + script: + - echo "Run a script that results in exit code 1. This job fails." + - exit 1 + allow_failure: + exit_codes: 137 + +test_job_2: + script: + - echo "Run a script that results in exit code 137. This job is allowed to fail." + - exit 137 + allow_failure: + exit_codes: + - 137 + - 255 +``` + +### `when` + +Use `when` to implement jobs that run in case of failure or despite the +failure. + +The valid values of `when` are: + +1. `on_success` (default) - Execute job only when all jobs in earlier stages succeed, + or are considered successful because they have `allow_failure: true`. +1. `on_failure` - Execute job only when at least one job in an earlier stage fails. +1. `always` - Execute job regardless of the status of jobs in earlier stages. +1. `manual` - Execute job [manually](#whenmanual). +1. `delayed` - [Delay the execution of a job](#whendelayed) for a specified duration. + Added in GitLab 11.14. +1. `never`: + - With job [`rules`](#rules), don't execute job. + - With [`workflow:rules`](#workflow), don't run pipeline. + +In the following example, the script: + +1. Executes `cleanup_build_job` only when `build_job` fails. +1. Always executes `cleanup_job` as the last step in pipeline regardless of + success or failure. +1. Executes `deploy_job` when you run it manually in the GitLab UI. + +```yaml +stages: + - build + - cleanup_build + - test + - deploy + - cleanup + +build_job: + stage: build + script: + - make build + +cleanup_build_job: + stage: cleanup_build + script: + - cleanup build when failed + when: on_failure + +test_job: + stage: test + script: + - make test + +deploy_job: + stage: deploy + script: + - make deploy + when: manual + +cleanup_job: + stage: cleanup + script: + - cleanup after jobs + when: always +``` + +#### `when:manual` + +A manual job is a type of job that is not executed automatically and must be explicitly +started by a user. You might want to use manual jobs for things like deploying to production. + +To make a job manual, add `when: manual` to its configuration. + +When the pipeline starts, manual jobs display as skipped and do not run automatically. +They can be started from the pipeline, job, [environment](../environments/index.md#configure-manual-deployments), +and deployment views. + +Manual jobs can be either optional or blocking: + +- **Optional**: Manual jobs have [`allow_failure: true](#allow_failure) set by default + and are considered optional. The status of an optional manual job does not contribute + to the overall pipeline status. A pipeline can succeed even if all its manual jobs fail. + +- **Blocking**: To make a blocking manual job, add `allow_failure: false` to its configuration. + Blocking manual jobs stop further execution of the pipeline at the stage where the + job is defined. To let the pipeline continue running, click **{play}** (play) on + the blocking manual job. + + Merge requests in projects with [merge when pipeline succeeds](../../user/project/merge_requests/merge_when_pipeline_succeeds.md) + enabled can't be merged with a blocked pipeline. Blocked pipelines show a status + of **blocked**. + +When you use [`rules:`](#rules), `allow_failure` defaults to `false`, including for manual jobs. + +To trigger a manual job, a user must have permission to merge to the assigned branch. +You can use [protected branches](../../user/project/protected_branches.md) to more strictly +[protect manual deployments](#protecting-manual-jobs) from being run by unauthorized users. + +In [GitLab 13.5](https://gitlab.com/gitlab-org/gitlab/-/issues/201938) and later, you +can use `when:manual` in the same job as [`trigger`](#trigger). In GitLab 13.4 and +earlier, using them together causes the error `jobs:#{job-name} when should be on_success, on_failure or always`. + +##### Protecting manual jobs **(PREMIUM)** + +Use [protected environments](../environments/protected_environments.md) +to define a list of users authorized to run a manual job. You can authorize only +the users associated with a protected environment to trigger manual jobs, which can: + +- More precisely limit who can deploy to an environment. +- Block a pipeline until an approved user "approves" it. + +To protect a manual job: + +1. Add an `environment` to the job. For example: + + ```yaml + deploy_prod: + stage: deploy + script: + - echo "Deploy to production server" + environment: + name: production + url: https://example.com + when: manual + rules: + - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH + ``` + +1. In the [protected environments settings](../environments/protected_environments.md#protecting-environments), + select the environment (`production` in this example) and add the users, roles or groups + that are authorized to trigger the manual job to the **Allowed to Deploy** list. Only those in + this list can trigger this manual job, as well as GitLab administrators + who are always able to use protected environments. + +You can use protected environments with blocking manual jobs to have a list of users +allowed to approve later pipeline stages. Add `allow_failure: false` to the protected +manual job and the pipeline's next stages only run after the manual job is triggered +by authorized users. + +#### `when:delayed` + +> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/51352) in GitLab 11.4. + +Use `when: delayed` to execute scripts after a waiting period, or if you want to avoid +jobs immediately entering the `pending` state. + +You can set the period with `start_in` keyword. The value of `start_in` is an elapsed time in seconds, unless a unit is +provided. `start_in` must be less than or equal to one week. Examples of valid values include: + +- `'5'` +- `5 seconds` +- `30 minutes` +- `1 day` +- `1 week` + +When a stage includes a delayed job, the pipeline doesn't progress until the delayed job finishes. +You can use this keyword to insert delays between different stages. + +The timer of a delayed job starts immediately after the previous stage completes. +Similar to other types of jobs, a delayed job's timer doesn't start unless the previous stage passes. + +The following example creates a job named `timed rollout 10%` that is executed 30 minutes after the previous stage completes: + +```yaml +timed rollout 10%: + stage: deploy + script: echo 'Rolling out 10% ...' + when: delayed + start_in: 30 minutes +``` + +To stop the active timer of a delayed job, click the **{time-out}** (**Unschedule**) button. +This job can no longer be scheduled to run automatically. You can, however, execute the job manually. + +To start a delayed job immediately, click the **Play** button. +Soon GitLab Runner picks up and starts the job. + +### `environment` + +Use `environment` to define the [environment](../environments/index.md) that a job deploys to. +For example: + +```yaml +deploy to production: + stage: deploy + script: git push production HEAD:main + environment: production +``` + +You can assign a value to the `environment` keyword by using: + +- Plain text, like `production`. +- Variables, including CI/CD variables, predefined, secure, or variables + defined in the `.gitlab-ci.yml` file. + +You can't use variables defined in a `script` section. + +If you specify an `environment` and no environment with that name exists, +an environment is created. + +#### `environment:name` + +Set a name for an [environment](../environments/index.md). For example: + +```yaml +deploy to production: + stage: deploy + script: git push production HEAD:main + environment: + name: production +``` + +Common environment names are `qa`, `staging`, and `production`, but you can use any +name you want. + +You can assign a value to the `name` keyword by using: + +- Plain text, like `staging`. +- Variables, including CI/CD variables, predefined, secure, or variables + defined in the `.gitlab-ci.yml` file. + +You can't use variables defined in a `script` section. + +The environment `name` can contain: + +- Letters +- Digits +- Spaces +- `-` +- `_` +- `/` +- `$` +- `{` +- `}` + +#### `environment:url` + +Set a URL for an [environment](../environments/index.md). For example: + +```yaml +deploy to production: + stage: deploy + script: git push production HEAD:main + environment: + name: production + url: https://prod.example.com +``` + +After the job completes, you can access the URL by using a button in the merge request, +environment, or deployment pages. + +You can assign a value to the `url` keyword by using: + +- Plain text, like `https://prod.example.com`. +- Variables, including CI/CD variables, predefined, secure, or variables + defined in the `.gitlab-ci.yml` file. + +You can't use variables defined in a `script` section. + +#### `environment:on_stop` + +Closing (stopping) environments can be achieved with the `on_stop` keyword +defined under `environment`. It declares a different job that runs to close the +environment. + +Read the `environment:action` section for an example. + +#### `environment:action` + +Use the `action` keyword to specify jobs that prepare, start, or stop environments. + +| **Value** | **Description** | +|-----------|---------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `start` | Default value. Indicates that job starts the environment. The deployment is created after the job starts. | +| `prepare` | Indicates that the job is only preparing the environment. It does not trigger deployments. [Read more about preparing environments](../environments/index.md#prepare-an-environment-without-creating-a-deployment). | +| `stop` | Indicates that job stops deployment. See the example below. | + +Take for instance: + +```yaml +review_app: + stage: deploy + script: make deploy-app + environment: + name: review/$CI_COMMIT_REF_NAME + url: https://$CI_ENVIRONMENT_SLUG.example.com + on_stop: stop_review_app + +stop_review_app: + stage: deploy + variables: + GIT_STRATEGY: none + script: make delete-app + when: manual + environment: + name: review/$CI_COMMIT_REF_NAME + action: stop +``` + +In the above example, the `review_app` job deploys to the `review` +environment. A new `stop_review_app` job is listed under `on_stop`. +After the `review_app` job is finished, it triggers the +`stop_review_app` job based on what is defined under `when`. In this case, +it is set to `manual`, so it needs a [manual action](#whenmanual) from +the GitLab UI to run. + +Also in the example, `GIT_STRATEGY` is set to `none`. If the +`stop_review_app` job is [automatically triggered](../environments/index.md#stopping-an-environment), +the runner won't try to check out the code after the branch is deleted. + +The example also overwrites global variables. If your `stop` `environment` job depends +on global variables, use [anchor variables](#yaml-anchors-for-variables) when you set the `GIT_STRATEGY` +to change the job without overriding the global variables. + +The `stop_review_app` job is **required** to have the following keywords defined: + +- `when`, defined at either: + - [The job level](#when). + - [In a rules clause](#rules). If you use `rules:` and `when: manual`, you should + also set [`allow_failure: true`](#allow_failure) so the pipeline can complete + even if the job doesn't run. +- `environment:name` +- `environment:action` + +Additionally, both jobs should have matching [`rules`](#only--except) +or [`only/except`](#only--except) configuration. + +In the examples above, if the configuration is not identical: + +- The `stop_review_app` job might not be included in all pipelines that include the `review_app` job. +- It is not possible to trigger the `action: stop` to stop the environment automatically. + +#### `environment:auto_stop_in` + +> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/20956) in GitLab 12.8. + +The `auto_stop_in` keyword is for specifying the lifetime of the environment, +that when expired, GitLab automatically stops them. + +For example, + +```yaml +review_app: + script: deploy-review-app + environment: + name: review/$CI_COMMIT_REF_NAME + auto_stop_in: 1 day +``` + +When the environment for `review_app` is created, the environment's lifetime is set to `1 day`. +Every time the review app is deployed, that lifetime is also reset to `1 day`. + +For more information, see +[the environments auto-stop documentation](../environments/index.md#stop-an-environment-after-a-certain-time-period) + +#### `environment:kubernetes` + +> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/27630) in GitLab 12.6. + +Use the `kubernetes` keyword to configure deployments to a +[Kubernetes cluster](../../user/project/clusters/index.md) that is associated with your project. + +For example: + +```yaml +deploy: + stage: deploy + script: make deploy-app + environment: + name: production + kubernetes: + namespace: production +``` + +This configuration sets up the `deploy` job to deploy to the `production` +environment, using the `production` +[Kubernetes namespace](https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/). + +For more information, see +[Available settings for `kubernetes`](../environments/index.md#configure-kubernetes-deployments). + +NOTE: +Kubernetes configuration is not supported for Kubernetes clusters +that are [managed by GitLab](../../user/project/clusters/index.md#gitlab-managed-clusters). +To follow progress on support for GitLab-managed clusters, see the +[relevant issue](https://gitlab.com/gitlab-org/gitlab/-/issues/38054). + +#### `environment:deployment_tier` + +> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/300741) in GitLab 13.10. + +Use the `deployment_tier` keyword to specify the tier of the deployment environment: + +```yaml +deploy: + script: echo + environment: + name: customer-portal + deployment_tier: production +``` + +For more information, +see [Deployment tier of environments](../environments/index.md#deployment-tier-of-environments). + +#### Dynamic environments + +Use CI/CD [variables](../variables/index.md) to dynamically name environments. + +For example: + +```yaml +deploy as review app: + stage: deploy + script: make deploy + environment: + name: review/$CI_COMMIT_REF_NAME + url: https://$CI_ENVIRONMENT_SLUG.example.com/ +``` + +The `deploy as review app` job is marked as a deployment to dynamically +create the `review/$CI_COMMIT_REF_NAME` environment. `$CI_COMMIT_REF_NAME` +is a [CI/CD variable](../variables/index.md) set by the runner. The +`$CI_ENVIRONMENT_SLUG` variable is based on the environment name, but suitable +for inclusion in URLs. If the `deploy as review app` job runs in a branch named +`pow`, this environment would be accessible with a URL like `https://review-pow.example.com/`. + +The common use case is to create dynamic environments for branches and use them +as Review Apps. You can see an example that uses Review Apps at +. + +### `cache` + +Use `cache` to specify a list of files and directories to +cache between jobs. You can only use paths that are in the local working copy. + +Caching is shared between pipelines and jobs. Caches are restored before [artifacts](#artifacts). + +Learn more about caches in [Caching in GitLab CI/CD](../caching/index.md). + +#### `cache:paths` + +Use the `cache:paths` keyword to choose which files or directories to cache. + +**Keyword type**: Job-specific. You can use it only as part of a job. + +**Possible inputs**: An array of paths relative to the project directory (`$CI_PROJECT_DIR`). +You can use wildcards that use [glob](https://en.wikipedia.org/wiki/Glob_(programming)) +patterns: + +- In [GitLab Runner 13.0](https://gitlab.com/gitlab-org/gitlab-runner/-/issues/2620) and later, +[`doublestar.Glob`](https://pkg.go.dev/github.com/bmatcuk/doublestar@v1.2.2?tab=doc#Match). +- In GitLab Runner 12.10 and earlier, +[`filepath.Match`](https://pkg.go.dev/path/filepath#Match). + +**Example of `cache:paths`**: + +Cache all files in `binaries` that end in `.apk` and the `.config` file: + +```yaml +rspec: + script: + - echo "This job uses a cache." + cache: + key: binaries-cache + paths: + - binaries/*.apk + - .config +``` + +**Related topics**: + +- See the [common `cache` use cases](../caching/index.md#common-use-cases-for-caches) for more + `cache:paths` examples. + +#### `cache:key` + +Use the `cache:key` keyword to give each cache a unique identifying key. All jobs +that use the same cache key use the same cache, including in different pipelines. + +If not set, the default key is `default`. All jobs with the `cache:` keyword but +no `cache:key` share the `default` cache. + +**Keyword type**: Job-specific. You can use it only as part of a job. + +**Possible inputs**: + +- A string. +- A [predefined variables](../variables/index.md). +- A combination of both. + +**Example of `cache:key`**: + +```yaml +cache-job: + script: + - echo "This job uses a cache." + cache: + key: binaries-cache-$CI_COMMIT_REF_SLUG + paths: + - binaries/ +``` + +**Additional details**: + +- If you use **Windows Batch** to run your shell scripts you need to replace + `$` with `%`. For example: `key: %CI_COMMIT_REF_SLUG%` +- The `cache:key` value can't contain: + + - The `/` character, or the equivalent URI-encoded `%2F`. + - Only the `.` character (any number), or the equivalent URI-encoded `%2E`. + +- The cache is shared between jobs, so if you're using different + paths for different jobs, you should also set a different `cache:key`. + Otherwise cache content can be overwritten. + +**Related topics**: + +- You can specify a [fallback cache key](../caching/index.md#use-a-fallback-cache-key) + to use if the specified `cache:key` is not found. +- You can [use multiple cache keys](../caching/index.md#use-multiple-caches) in a single job. +- See the [common `cache` use cases](../caching/index.md#common-use-cases-for-caches) for more + `cache:key` examples. + +##### `cache:key:files` + +> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/18986) in GitLab v12.5. + +Use the `cache:key:files` keyword to generate a new key when one or two specific files +change. `cache:key:files` lets you reuse some caches, and rebuild them less often, +which speeds up subsequent pipeline runs. + +**Keyword type**: Job-specific. You can use it only as part of a job. + +**Possible inputs**: An array of one or two file paths. + +**Example of `cache:key:files`**: + +```yaml +cache-job: + script: + - echo "This job uses a cache." + cache: + key: + files: + - Gemfile.lock + - package.json + paths: + - vendor/ruby + - node_modules +``` + +This example creates a cache for Ruby and Node.js dependencies. The cache +is tied to the current versions of the `Gemfile.lock` and `package.json` files. When one of +these files changes, a new cache key is computed and a new cache is created. Any future +job runs that use the same `Gemfile.lock` and `package.json` with `cache:key:files` +use the new cache, instead of rebuilding the dependencies. + +**Additional details**: The cache `key` is a SHA computed from the most recent commits +that changed each listed file. If neither file is changed in any commits, the +fallback key is `default`. + +##### `cache:key:prefix` + +> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/18986) in GitLab v12.5. + +Use `cache:key:prefix` to combine a prefix with the SHA computed for [`cache:key:files`](#cachekeyfiles). + +**Keyword type**: Job-specific. You can use it only as part of a job. + +**Possible inputs**: + +- A string +- A [predefined variables](../variables/index.md) +- A combination of both. + +**Example of `cache:key:prefix`**: + +```yaml +rspec: + script: + - echo "This rspec job uses a cache." + cache: + key: + files: + - Gemfile.lock + prefix: $CI_JOB_NAME + paths: + - vendor/ruby +``` + +For example, adding a `prefix` of `$CI_JOB_NAME` causes the key to look like `rspec-feef9576d21ee9b6a32e30c5c79d0a0ceb68d1e5`. +If a branch changes `Gemfile.lock`, that branch has a new SHA checksum for `cache:key:files`. +A new cache key is generated, and a new cache is created for that key. If `Gemfile.lock` +is not found, the prefix is added to `default`, so the key in the example would be `rspec-default`. + +**Additional details**: If no file in `cache:key:files` is changed in any commits, +the prefix is added to the `default` key. + +#### `cache:untracked` + +Use `untracked: true` to cache all files that are untracked in your Git repository: + +**Keyword type**: Job-specific. You can use it only as part of a job. + +**Possible inputs**: `true` or `false` (default). + +**Example of `cache:untracked`**: + +```yaml +rspec: + script: test + cache: + untracked: true +``` + +**Additional details**: + +- You can combine `cache:untracked` with `cache:paths` to cache all untracked files + as well as files in the configured paths. For example: + + ```yaml + rspec: + script: test + cache: + untracked: true + paths: + - binaries/ + ``` + +#### `cache:when` + +> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/18969) in GitLab 13.5 and GitLab Runner v13.5.0. + +Use `cache:when` to define when to save the cache, based on the status of the job. + +**Keyword type**: Job-specific. You can use it only as part of a job. + +**Possible inputs**: + +- `on_success` (default): Save the cache only when the job succeeds. +- `on_failure`: Save the cache only when the job fails. +- `always`: Always save the cache. + +**Example of `cache:untracked`**: + +```yaml +rspec: + script: rspec + cache: + paths: + - rspec/ + when: 'always' +``` + +This example stores the cache whether or not the job fails or succeeds. + +#### `cache:policy` + +To change the upload and download behavior of a cache, use the `cache:policy` keyword. +By default, the job downloads the cache when the job starts, and uploads changes +to the cache when the job ends. This is the `pull-push` policy (default). + +To set a job to only download the cache when the job starts, but never upload changes +when the job finishes, use `cache:policy:pull`. + +To set a job to only upload a cache when the job finishes, but never download the +cache when the job starts, use `cache:policy:push`. + +Use the `pull` policy when you have many jobs executing in parallel that use the same cache. +This policy speeds up job execution and reduces load on the cache server. You can +use a job with the `push` policy to build the cache. + +**Keyword type**: Job-specific. You can use it only as part of a job. + +**Possible inputs**: + +- `pull` +- `push` +- `pull-push` (default) + +**Example of `cache:policy`**: + +```yaml +prepare-dependencies-job: + stage: build + cache: + key: gems + paths: + - vendor/bundle + policy: push + script: + - echo "This job only downloads dependencies and builds the cache." + - echo "Downloading dependencies..." + +faster-test-job: + stage: test + cache: + key: gems + paths: + - vendor/bundle + policy: pull + script: + - echo "This job script uses the cache, but does not update it." + - echo "Running tests..." +``` + +### `artifacts` + +Use `artifacts` to specify a list of files and directories that are +attached to the job when it [succeeds, fails, or always](#artifactswhen). + +The artifacts are sent to GitLab after the job finishes. They are +available for download in the GitLab UI if the size is not +larger than the [maximum artifact size](../../user/gitlab_com/index.md#gitlab-cicd). + +By default, jobs in later stages automatically download all the artifacts created +by jobs in earlier stages. You can control artifact download behavior in jobs with +[`dependencies`](#dependencies). + +When using the [`needs`](#artifact-downloads-with-needs) keyword, jobs can only download +artifacts from the jobs defined in the `needs` configuration. + +Job artifacts are only collected for successful jobs by default, and +artifacts are restored after [caches](#cache). + +[Read more about artifacts](../pipelines/job_artifacts.md). + +#### `dependencies` + +By default, all `artifacts` from previous stages +are passed to each job. However, you can use the `dependencies` keyword to +define a limited list of jobs to fetch artifacts from. You can also set a job to download no artifacts at all. + +To use this feature, define `dependencies` in context of the job and pass +a list of all previous jobs the artifacts should be downloaded from. + +You can define jobs from stages that were executed before the current one. +An error occurs if you define jobs from the current or an upcoming stage. + +To prevent a job from downloading artifacts, define an empty array. + +When you use `dependencies`, the status of the previous job is not considered. +If a job fails or it's a manual job that isn't triggered, no error occurs. + +The following example defines two jobs with artifacts: `build:osx` and +`build:linux`. When the `test:osx` is executed, the artifacts from `build:osx` +are downloaded and extracted in the context of the build. The same happens +for `test:linux` and artifacts from `build:linux`. + +The job `deploy` downloads artifacts from all previous jobs because of +the [stage](#stages) precedence: + +```yaml +build:osx: + stage: build + script: make build:osx + artifacts: + paths: + - binaries/ + +build:linux: + stage: build + script: make build:linux + artifacts: + paths: + - binaries/ + +test:osx: + stage: test + script: make test:osx + dependencies: + - build:osx + +test:linux: + stage: test + script: make test:linux + dependencies: + - build:linux + +deploy: + stage: deploy + script: make deploy +``` + +##### When a dependent job fails + +> Introduced in GitLab 10.3. + +If the artifacts of the job that is set as a dependency are +[expired](#artifactsexpire_in) or +[deleted](../pipelines/job_artifacts.md#delete-job-artifacts), then +the dependent job fails. + +#### `artifacts:exclude` + +> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/15122) in GitLab 13.1 +> - Requires GitLab Runner 13.1 + +`exclude` makes it possible to prevent files from being added to an artifacts +archive. + +Similar to [`artifacts:paths`](#artifactspaths), `exclude` paths are relative +to the project directory. You can use Wildcards that use +[glob](https://en.wikipedia.org/wiki/Glob_(programming)) or +[`doublestar.PathMatch`](https://pkg.go.dev/github.com/bmatcuk/doublestar@v1.2.2?tab=doc#PathMatch) patterns. + +For example, to store all files in `binaries/`, but not `*.o` files located in +subdirectories of `binaries/`: + +```yaml +artifacts: + paths: + - binaries/ + exclude: + - binaries/**/*.o +``` + +Unlike [`artifacts:paths`](#artifactspaths), `exclude` paths are not recursive. To exclude all of the contents of a directory, you can match them explicitly rather than matching the directory itself. + +For example, to store all files in `binaries/` but nothing located in the `temp/` subdirectory: + +```yaml +artifacts: + paths: + - binaries/ + exclude: + - binaries/temp/**/* +``` + +Files matched by [`artifacts:untracked`](#artifactsuntracked) can be excluded using +`artifacts:exclude` too. + +#### `artifacts:expire_in` + +> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/16267) in GitLab 13.0 behind a disabled feature flag, the latest job artifacts are kept regardless of expiry time. +> - [Made default behavior](https://gitlab.com/gitlab-org/gitlab/-/issues/229936) in GitLab 13.4. +> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/241026) in GitLab 13.8, keeping latest job artifacts can be disabled at the project level. +> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/276583) in GitLab 13.9, keeping latest job artifacts can be disabled instance-wide. +> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/321323) in GitLab 13.12, the latest pipeline artifacts are kept regardless of expiry time. + +Use `expire_in` to specify how long [job artifacts](../pipelines/job_artifacts.md) are stored before +they expire and are deleted. The `expire_in` setting does not affect: + +- Artifacts from the latest job, unless this keeping the latest job artifacts is: + - [Disabled at the project level](../pipelines/job_artifacts.md#keep-artifacts-from-most-recent-successful-jobs). + - [Disabled instance-wide](../../user/admin_area/settings/continuous_integration.md#keep-the-latest-artifacts-for-all-jobs-in-the-latest-successful-pipelines). +- [Pipeline artifacts](../pipelines/pipeline_artifacts.md). It's not possible to specify an + expiration date for these: + - Pipeline artifacts from the latest pipeline are kept forever. + - Other pipeline artifacts are erased after one week. + +The value of `expire_in` is an elapsed time in seconds, unless a unit is provided. Valid values +include: + +- `'42'` +- `42 seconds` +- `3 mins 4 sec` +- `2 hrs 20 min` +- `2h20min` +- `6 mos 1 day` +- `47 yrs 6 mos and 4d` +- `3 weeks and 2 days` +- `never` + +To expire artifacts one week after being uploaded: + +```yaml +job: + artifacts: + expire_in: 1 week +``` + +The expiration time period begins when the artifact is uploaded and stored on GitLab. If the expiry +time is not defined, it defaults to the +[instance wide setting](../../user/admin_area/settings/continuous_integration.md#default-artifacts-expiration) +(30 days by default). + +To override the expiration date and protect artifacts from being automatically deleted: + +- Use the **Keep** button on the job page. +- [In GitLab 13.3 and later](https://gitlab.com/gitlab-org/gitlab/-/issues/22761), set the value of + `expire_in` to `never`. + +After their expiry, artifacts are deleted hourly by default (using a cron job), and are not +accessible anymore. + +#### `artifacts:expose_as` + +> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/15018) in GitLab 12.5. + +Use the `expose_as` keyword to expose [job artifacts](../pipelines/job_artifacts.md) +in the [merge request](../../user/project/merge_requests/index.md) UI. + +For example, to match a single file: + +```yaml +test: + script: ["echo 'test' > file.txt"] + artifacts: + expose_as: 'artifact 1' + paths: ['file.txt'] +``` + +With this configuration, GitLab adds a link **artifact 1** to the relevant merge request +that points to `file1.txt`. To access the link, select **View exposed artifact** +below the pipeline graph in the merge request overview. + +An example that matches an entire directory: + +```yaml +test: + script: ["mkdir test && echo 'test' > test/file.txt"] + artifacts: + expose_as: 'artifact 1' + paths: ['test/'] +``` + +Note the following: + +- Artifacts do not display in the merge request UI when using variables to define the `artifacts:paths`. +- A maximum of 10 job artifacts per merge request can be exposed. +- Glob patterns are unsupported. +- If a directory is specified, the link is to the job [artifacts browser](../pipelines/job_artifacts.md#download-job-artifacts) if there is more than + one file in the directory. +- For exposed single file artifacts with `.html`, `.htm`, `.txt`, `.json`, `.xml`, + and `.log` extensions, if [GitLab Pages](../../administration/pages/index.md) is: + - Enabled, GitLab automatically renders the artifact. + - Not enabled, the file is displayed in the artifacts browser. + +#### `artifacts:name` + +Use the `name` directive to define the name of the created artifacts +archive. You can specify a unique name for every archive. The `artifacts:name` +variable can make use of any of the [predefined variables](../variables/index.md). +The default name is `artifacts`, which becomes `artifacts.zip` when you download it. + +To create an archive with a name of the current job: + +```yaml +job: + artifacts: + name: "$CI_JOB_NAME" + paths: + - binaries/ +``` + +To create an archive with a name of the current branch or tag including only +the binaries directory: + +```yaml +job: + artifacts: + name: "$CI_COMMIT_REF_NAME" + paths: + - binaries/ +``` + +If your branch-name contains forward slashes +(for example `feature/my-feature`) it's advised to use `$CI_COMMIT_REF_SLUG` +instead of `$CI_COMMIT_REF_NAME` for proper naming of the artifact. + +To create an archive with a name of the current job and the current branch or +tag including only the binaries directory: + +```yaml +job: + artifacts: + name: "$CI_JOB_NAME-$CI_COMMIT_REF_NAME" + paths: + - binaries/ +``` + +To create an archive with a name of the current [stage](#stages) and branch name: + +```yaml +job: + artifacts: + name: "$CI_JOB_STAGE-$CI_COMMIT_REF_NAME" + paths: + - binaries/ +``` + +--- + +If you use **Windows Batch** to run your shell scripts you need to replace +`$` with `%`: + +```yaml +job: + artifacts: + name: "%CI_JOB_STAGE%-%CI_COMMIT_REF_NAME%" + paths: + - binaries/ +``` + +If you use **Windows PowerShell** to run your shell scripts you need to replace +`$` with `$env:`: + +```yaml +job: + artifacts: + name: "$env:CI_JOB_STAGE-$env:CI_COMMIT_REF_NAME" + paths: + - binaries/ +``` + +#### `artifacts:paths` + +Paths are relative to the project directory (`$CI_PROJECT_DIR`) and can't directly +link outside it. You can use Wildcards that use [glob](https://en.wikipedia.org/wiki/Glob_(programming)) +patterns and: + +- In [GitLab Runner 13.0](https://gitlab.com/gitlab-org/gitlab-runner/-/issues/2620) and later, +[`doublestar.Glob`](https://pkg.go.dev/github.com/bmatcuk/doublestar@v1.2.2?tab=doc#Match). +- In GitLab Runner 12.10 and earlier, +[`filepath.Match`](https://pkg.go.dev/path/filepath#Match). + +To restrict which jobs a specific job fetches artifacts from, see [dependencies](#dependencies). + +Send all files in `binaries` and `.config`: + +```yaml +artifacts: + paths: + - binaries/ + - .config +``` + +To disable artifact passing, define the job with empty [dependencies](#dependencies): + +```yaml +job: + stage: build + script: make build + dependencies: [] +``` + +You may want to create artifacts only for tagged releases to avoid filling the +build server storage with temporary build artifacts. + +Create artifacts only for tags (`default-job` doesn't create artifacts): + +```yaml +default-job: + script: + - mvn test -U + rules: + - if: $CI_COMMIT_BRANCH + +release-job: + script: + - mvn package -U + artifacts: + paths: + - target/*.war + rules: + - if: $CI_COMMIT_TAG +``` + +You can use wildcards for directories too. For example, if you want to get all the files inside the directories that end with `xyz`: + +```yaml +job: + artifacts: + paths: + - path/*xyz/* +``` + +#### `artifacts:public` + +> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/49775) in GitLab 13.8 +> - It's [deployed behind a feature flag](../../user/feature_flags.md), disabled by default. +> - It's disabled on GitLab.com. +> - It's recommended for production use. + +Use `artifacts:public` to determine whether the job artifacts should be +publicly available. + +The default for `artifacts:public` is `true` which means that the artifacts in +public pipelines are available for download by anonymous and guest users: + +```yaml +artifacts: + public: true +``` + +To deny read access for anonymous and guest users to artifacts in public +pipelines, set `artifacts:public` to `false`: + +```yaml +artifacts: + public: false +``` + +#### `artifacts:reports` + +> - [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/20390) in GitLab 11.2. +> - Requires GitLab Runner 11.2 and above. + +Use [`artifacts:reports`](#artifactsreports) +to collect test reports, code quality reports, and security reports from jobs. +It also exposes these reports in the GitLab UI (merge requests, pipeline views, and security dashboards). + +The test reports are collected regardless of the job results (success or failure). +You can use [`artifacts:expire_in`](#artifactsexpire_in) to set up an expiration +date for their artifacts. + +If you also want the ability to browse the report output files, include the +[`artifacts:paths`](#artifactspaths) keyword. + +##### `artifacts:reports:api_fuzzing` **(ULTIMATE)** + +> - Introduced in GitLab 13.4. +> - Requires GitLab Runner 13.4 or later. + +The `api_fuzzing` report collects [API Fuzzing bugs](../../user/application_security/api_fuzzing/index.md) +as artifacts. + +The collected API Fuzzing report uploads to GitLab as an artifact and is summarized in merge +requests and the pipeline view. It's also used to provide data for security dashboards. + +##### `artifacts:reports:cobertura` + +> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/3708) in GitLab 12.9. +> - Requires [GitLab Runner](https://docs.gitlab.com/runner/) 11.5 and above. + +The `cobertura` report collects [Cobertura coverage XML files](../../user/project/merge_requests/test_coverage_visualization.md). +The collected Cobertura coverage reports upload to GitLab as an artifact +and display in merge requests. + +Cobertura was originally developed for Java, but there are many +third party ports for other languages like JavaScript, Python, Ruby, and so on. + +##### `artifacts:reports:codequality` + +> - Introduced in GitLab 11.5. +> - [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/212499) to GitLab Free in 13.2. +> - Requires GitLab Runner 11.5 and above. + +The `codequality` report collects [Code Quality issues](../../user/project/merge_requests/code_quality.md) +as artifacts. + +The collected Code Quality report uploads to GitLab as an artifact and is summarized in merge requests. + +##### `artifacts:reports:container_scanning` **(ULTIMATE)** + +> - Introduced in GitLab 11.5. +> - Requires GitLab Runner 11.5 and above. + +The `container_scanning` report collects [Container Scanning vulnerabilities](../../user/application_security/container_scanning/index.md) +as artifacts. + +The collected Container Scanning report uploads to GitLab as an artifact and +is summarized in merge requests and the pipeline view. It's also used to provide data for security +dashboards. + +##### `artifacts:reports:coverage_fuzzing` **(ULTIMATE)** + +> - Introduced in GitLab 13.4. +> - Requires GitLab Runner 13.4 or later. + +The `coverage_fuzzing` report collects [coverage fuzzing bugs](../../user/application_security/coverage_fuzzing/index.md) +as artifacts. + +The collected coverage fuzzing report uploads to GitLab as an artifact and is summarized in merge +requests and the pipeline view. It's also used to provide data for security dashboards. + +##### `artifacts:reports:dast` **(ULTIMATE)** + +> - Introduced in GitLab 11.5. +> - Requires GitLab Runner 11.5 and above. + +The `dast` report collects [DAST vulnerabilities](../../user/application_security/dast/index.md) +as artifacts. + +The collected DAST report uploads to GitLab as an artifact and is summarized in merge requests and the pipeline view. It's also used to provide data for security +dashboards. + +##### `artifacts:reports:dependency_scanning` **(ULTIMATE)** + +> - Introduced in GitLab 11.5. +> - Requires GitLab Runner 11.5 and above. + +The `dependency_scanning` report collects [Dependency Scanning vulnerabilities](../../user/application_security/dependency_scanning/index.md) +as artifacts. + +The collected Dependency Scanning report uploads to GitLab as an artifact and is summarized in merge requests and the pipeline view. It's also used to provide data for security +dashboards. + +##### `artifacts:reports:dotenv` + +> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/17066) in GitLab 12.9. +> - Requires GitLab Runner 11.5 and later. + +The `dotenv` report collects a set of environment variables as artifacts. + +The collected variables are registered as runtime-created variables of the job, +which is useful to [set dynamic environment URLs after a job finishes](../environments/index.md#set-dynamic-environment-urls-after-a-job-finishes). + +There are a couple of exceptions to the [original dotenv rules](https://github.com/motdotla/dotenv#rules): + +- The variable key can contain only letters, digits, and underscores (`_`). +- The maximum size of the `.env` file is 5 KB. +- In GitLab 13.5 and older, the maximum number of inherited variables is 10. +- In [GitLab 13.6 and later](https://gitlab.com/gitlab-org/gitlab/-/issues/247913), + the maximum number of inherited variables is 20. +- Variable substitution in the `.env` file is not supported. +- The `.env` file can't have empty lines or comments (starting with `#`). +- Key values in the `env` file cannot have spaces or newline characters (`\n`), including when using single or double quotes. +- Quote escaping during parsing (`key = 'value'` -> `{key: "value"}`) is not supported. + +##### `artifacts:reports:junit` + +> - [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/20390) in GitLab 11.2. +> - Requires GitLab Runner 11.2 and above. + +The `junit` report collects [JUnit report format XML files](https://www.ibm.com/support/knowledgecenter/en/SSQ2R2_14.1.0/com.ibm.rsar.analysis.codereview.cobol.doc/topics/cac_useresults_junit.html) +as artifacts. Although JUnit was originally developed in Java, there are many +third party ports for other +languages like JavaScript, Python, Ruby, and so on. + +See [Unit test reports](../unit_test_reports.md) for more details and examples. +Below is an example of collecting a JUnit report format XML file from Ruby's RSpec test tool: + +```yaml +rspec: + stage: test + script: + - bundle install + - rspec --format RspecJunitFormatter --out rspec.xml + artifacts: + reports: + junit: rspec.xml +``` + +The collected Unit test reports upload to GitLab as an artifact and display in merge requests. + +If the JUnit tool you use exports to multiple XML files, specify +multiple test report paths within a single job to +concatenate them into a single file. Use a filename pattern (`junit: rspec-*.xml`), +an array of filenames (`junit: [rspec-1.xml, rspec-2.xml, rspec-3.xml]`), or a +combination thereof (`junit: [rspec.xml, test-results/TEST-*.xml]`). + +##### `artifacts:reports:license_scanning` **(ULTIMATE)** + +> - Introduced in GitLab 12.8. +> - Requires GitLab Runner 11.5 and above. + +The `license_scanning` report collects [Licenses](../../user/compliance/license_compliance/index.md) +as artifacts. + +The License Compliance report uploads to GitLab as an artifact and displays automatically in merge requests and the pipeline view, and provide data for security +dashboards. + +##### `artifacts:reports:load_performance` **(PREMIUM)** + +> - Introduced in [GitLab 13.2](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/35260) in [GitLab Premium](https://about.gitlab.com/pricing/) 13.2. +> - Requires GitLab Runner 11.5 and above. + +The `load_performance` report collects [Load Performance Testing metrics](../../user/project/merge_requests/load_performance_testing.md) +as artifacts. + +The report is uploaded to GitLab as an artifact and is +shown in merge requests automatically. + +##### `artifacts:reports:metrics` **(PREMIUM)** + +> Introduced in GitLab 11.10. + +The `metrics` report collects [Metrics](../metrics_reports.md) +as artifacts. + +The collected Metrics report uploads to GitLab as an artifact and displays in merge requests. + +##### `artifacts:reports:browser_performance` **(PREMIUM)** + +> - Introduced in GitLab 11.5. +> - Requires GitLab Runner 11.5 and above. +> - [Name changed](https://gitlab.com/gitlab-org/gitlab/-/issues/225914) from `artifacts:reports:performance` in GitLab 14.0. + +The `browser_performance` report collects [Browser Performance Testing metrics](../../user/project/merge_requests/browser_performance_testing.md) +as artifacts. + +The collected Browser Performance report uploads to GitLab as an artifact and displays in merge requests. + +##### `artifacts:reports:requirements` **(ULTIMATE)** + +> - [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/2859) in GitLab 13.1. +> - Requires GitLab Runner 11.5 and above. + +The `requirements` report collects `requirements.json` files as artifacts. + +The collected Requirements report uploads to GitLab as an artifact and +existing [requirements](../../user/project/requirements/index.md) are +marked as Satisfied. + +##### `artifacts:reports:sast` + +> - Introduced in GitLab 11.5. +> - Made [available in all tiers](https://gitlab.com/groups/gitlab-org/-/epics/2098) in GitLab 13.3. +> - Requires GitLab Runner 11.5 and above. + +The `sast` report collects [SAST vulnerabilities](../../user/application_security/sast/index.md) +as artifacts. + +The collected SAST report uploads to GitLab as an artifact and is summarized +in merge requests and the pipeline view. It's also used to provide data for security +dashboards. + +##### `artifacts:reports:secret_detection` + +> - Introduced in GitLab 13.1. +> - Made [available in all tiers](https://gitlab.com/gitlab-org/gitlab/-/issues/222788) in GitLab + 13.3. +> - Requires GitLab Runner 11.5 and above. + +The `secret-detection` report collects [detected secrets](../../user/application_security/secret_detection/index.md) +as artifacts. + +The collected Secret Detection report is uploaded to GitLab as an artifact and summarized +in the merge requests and pipeline view. It's also used to provide data for security +dashboards. + +##### `artifacts:reports:terraform` + +> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/207528) in GitLab 13.0. +> - Requires [GitLab Runner](https://docs.gitlab.com/runner/) 11.5 and above. + +The `terraform` report obtains a Terraform `tfplan.json` file. [JQ processing required to remove credentials](../../user/infrastructure/mr_integration.md#setup). The collected Terraform +plan report uploads to GitLab as an artifact and displays +in merge requests. For more information, see +[Output `terraform plan` information into a merge request](../../user/infrastructure/mr_integration.md). + +#### `artifacts:untracked` + +Use `artifacts:untracked` to add all Git untracked files as artifacts (along +with the paths defined in `artifacts:paths`). `artifacts:untracked` ignores configuration +in the repository's `.gitignore` file. + +Send all Git untracked files: + +```yaml +artifacts: + untracked: true +``` + +Send all Git untracked files and files in `binaries`: + +```yaml +artifacts: + untracked: true + paths: + - binaries/ +``` + +Send all untracked files but [exclude](#artifactsexclude) `*.txt`: + +```yaml +artifacts: + untracked: true + exclude: + - "*.txt" +``` + +#### `artifacts:when` + +Use `artifacts:when` to upload artifacts on job failure or despite the +failure. + +`artifacts:when` can be set to one of the following values: + +1. `on_success` (default): Upload artifacts only when the job succeeds. +1. `on_failure`: Upload artifacts only when the job fails. +1. `always`: Always upload artifacts. Useful, for example, when + [uploading artifacts](../unit_test_reports.md#viewing-junit-screenshots-on-gitlab) required to + troubleshoot failing tests. + +For example, to upload artifacts only when a job fails: + +```yaml +job: + artifacts: + when: on_failure +``` + +### `coverage` + +Use `coverage` to configure how code coverage is extracted from the +job output. + +Regular expressions are the only valid kind of value expected here. So, using +surrounding `/` is mandatory to consistently and explicitly represent +a regular expression string. You must escape special characters if you want to +match them literally. + +For example: + +```yaml +job1: + script: rspec + coverage: '/Code coverage: \d+\.\d+/' +``` + +The coverage is shown in the UI if at least one line in the job output matches the regular expression. +If there is more than one matched line in the job output, the last line is used. +For the matched line, the first occurrence of `\d+(\.\d+)?` is the code coverage. +Leading zeros are removed. + +Coverage output from [child pipelines](../parent_child_pipelines.md) is not recorded +or displayed. Check [the related issue](https://gitlab.com/gitlab-org/gitlab/-/issues/280818) +for more details. + +### `retry` + +> [Introduced](https://gitlab.com/gitlab-org/gitlab-runner/-/issues/3515) in GitLab 11.5, you can control which failures to retry on. + +Use `retry` to configure how many times a job is retried in +case of a failure. + +When a job fails, the job is processed again, +until the limit specified by the `retry` keyword is reached. + +If `retry` is set to `2`, and a job succeeds in a second run (first retry), it is not retried. +The `retry` value must be a positive integer, from `0` to `2` +(two retries maximum, three runs in total). + +The following example retries all failure cases: + +```yaml +test: + script: rspec + retry: 2 +``` + +By default, a job is retried on all failure cases. To have better control +over which failures to retry, `retry` can be a hash with the following keys: + +- `max`: The maximum number of retries. +- `when`: The failure cases to retry. + +To retry only runner system failures at maximum two times: + +```yaml +test: + script: rspec + retry: + max: 2 + when: runner_system_failure +``` + +If there is another failure, other than a runner system failure, the job +is not retried. + +To retry on multiple failure cases, `when` can also be an array of failures: + +```yaml +test: + script: rspec + retry: + max: 2 + when: + - runner_system_failure + - stuck_or_timeout_failure +``` + +Possible values for `when` are: + + + +- `always`: Retry on any failure (default). +- `unknown_failure`: Retry when the failure reason is unknown. +- `script_failure`: Retry when the script failed. +- `api_failure`: Retry on API failure. +- `stuck_or_timeout_failure`: Retry when the job got stuck or timed out. +- `runner_system_failure`: Retry if there is a runner system failure (for example, job setup failed). +- `missing_dependency_failure`: Retry if a dependency is missing. +- `runner_unsupported`: Retry if the runner is unsupported. +- `stale_schedule`: Retry if a delayed job could not be executed. +- `job_execution_timeout`: Retry if the script exceeded the maximum execution time set for the job. +- `archived_failure`: Retry if the job is archived and can't be run. +- `unmet_prerequisites`: Retry if the job failed to complete prerequisite tasks. +- `scheduler_failure`: Retry if the scheduler failed to assign the job to a runner. +- `data_integrity_failure`: Retry if there is a structural integrity problem detected. + +You can specify the number of [retry attempts for certain stages of job execution](../runners/configure_runners.md#job-stages-attempts) using variables. + +### `timeout` + +> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/14887) in GitLab 12.3. + +Use `timeout` to configure a timeout for a specific job. For example: + +```yaml +build: + script: build.sh + timeout: 3 hours 30 minutes + +test: + script: rspec + timeout: 3h 30m +``` + +The job-level timeout can exceed the +[project-level timeout](../pipelines/settings.md#timeout) but can't +exceed the runner-specific timeout. + +### `parallel` + +> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/21480) in GitLab 11.5. + +Use `parallel` to configure how many instances of a job to run in parallel. +The value can be from 2 to 50. + +The `parallel` keyword creates N instances of the same job that run in parallel. +They are named sequentially from `job_name 1/N` to `job_name N/N`: + +```yaml +test: + script: rspec + parallel: 5 +``` + +Every parallel job has a `CI_NODE_INDEX` and `CI_NODE_TOTAL` +[predefined CI/CD variable](../variables/index.md#predefined-cicd-variables) set. + +Different languages and test suites have different methods to enable parallelization. +For example, use [Semaphore Test Boosters](https://github.com/renderedtext/test-boosters) +and RSpec to run Ruby tests in parallel: + +```ruby +# Gemfile +source 'https://rubygems.org' + +gem 'rspec' +gem 'semaphore_test_boosters' +``` + +```yaml +test: + parallel: 3 + script: + - bundle + - bundle exec rspec_booster --job $CI_NODE_INDEX/$CI_NODE_TOTAL +``` + +WARNING: +Test Boosters reports usage statistics to the author. + +You can then navigate to the **Jobs** tab of a new pipeline build and see your RSpec +job split into three separate jobs. + +#### Parallel `matrix` jobs + +> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/15356) in GitLab 13.3. + +Use `matrix:` to run a job multiple times in parallel in a single pipeline, +but with different variable values for each instance of the job. +There can be from 2 to 50 jobs. + +Jobs can only run in parallel if there are multiple runners, or a single runner is +[configured to run multiple jobs concurrently](#use-your-own-runners). + +Every job gets the same `CI_NODE_TOTAL` [CI/CD variable](../variables/index.md#predefined-cicd-variables) value, and a unique `CI_NODE_INDEX` value. + +```yaml +deploystacks: + stage: deploy + script: + - bin/deploy + parallel: + matrix: + - PROVIDER: aws + STACK: + - monitoring + - app1 + - app2 + - PROVIDER: ovh + STACK: [monitoring, backup, app] + - PROVIDER: [gcp, vultr] + STACK: [data, processing] +``` + +The following example generates 10 parallel `deploystacks` jobs, each with different values +for `PROVIDER` and `STACK`: + +```plaintext +deploystacks: [aws, monitoring] +deploystacks: [aws, app1] +deploystacks: [aws, app2] +deploystacks: [ovh, monitoring] +deploystacks: [ovh, backup] +deploystacks: [ovh, app] +deploystacks: [gcp, data] +deploystacks: [gcp, processing] +deploystacks: [vultr, data] +deploystacks: [vultr, processing] +``` + +The job naming style was [improved in GitLab 13.4](https://gitlab.com/gitlab-org/gitlab/-/issues/230452). + +##### One-dimensional `matrix` jobs + +> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/26362) in GitLab 13.5. + +You can also have one-dimensional matrices with a single job: + +```yaml +deploystacks: + stage: deploy + script: + - bin/deploy + parallel: + matrix: + - PROVIDER: [aws, ovh, gcp, vultr] +``` + +##### Parallel `matrix` trigger jobs + +> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/270957) in GitLab 13.10. + +Use `matrix:` to run a [trigger](#trigger) job multiple times in parallel in a single pipeline, +but with different variable values for each instance of the job. + +```yaml +deploystacks: + stage: deploy + trigger: + include: path/to/child-pipeline.yml + parallel: + matrix: + - PROVIDER: aws + STACK: [monitoring, app1] + - PROVIDER: ovh + STACK: [monitoring, backup] + - PROVIDER: [gcp, vultr] + STACK: [data] +``` + +This example generates 6 parallel `deploystacks` trigger jobs, each with different values +for `PROVIDER` and `STACK`, and they create 6 different child pipelines with those variables. + +```plaintext +deploystacks: [aws, monitoring] +deploystacks: [aws, app1] +deploystacks: [ovh, monitoring] +deploystacks: [ovh, backup] +deploystacks: [gcp, data] +deploystacks: [vultr, data] +``` + +### `trigger` + +> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/8997) in [GitLab Premium](https://about.gitlab.com/pricing/) 11.8. +> - [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/199224) to GitLab Free in 12.8. + +Use `trigger` to define a downstream pipeline trigger. When GitLab starts a `trigger` job, +a downstream pipeline is created. + +Jobs with `trigger` can only use a [limited set of keywords](../multi_project_pipelines.md#define-multi-project-pipelines-in-your-gitlab-ciyml-file). +For example, you can't run commands with [`script`](#script), [`before_script`](#before_script), +or [`after_script`](#after_script). + +You can use this keyword to create two different types of downstream pipelines: + +- [Multi-project pipelines](../multi_project_pipelines.md#define-multi-project-pipelines-in-your-gitlab-ciyml-file) +- [Child pipelines](../parent_child_pipelines.md) + +[In GitLab 13.2](https://gitlab.com/gitlab-org/gitlab/-/issues/197140/) and later, you can +view which job triggered a downstream pipeline. In the [pipeline graph](../pipelines/index.md#visualize-pipelines), +hover over the downstream pipeline job. + +In [GitLab 13.5](https://gitlab.com/gitlab-org/gitlab/-/issues/201938) and later, you +can use [`when:manual`](#whenmanual) in the same job as `trigger`. In GitLab 13.4 and +earlier, using them together causes the error `jobs:#{job-name} when should be on_success, on_failure or always`. +You [cannot start `manual` trigger jobs with the API](https://gitlab.com/gitlab-org/gitlab/-/issues/284086). + +#### Basic `trigger` syntax for multi-project pipelines + +You can configure a downstream trigger by using the `trigger` keyword +with a full path to a downstream project: + +```yaml +rspec: + stage: test + script: bundle exec rspec + +staging: + stage: deploy + trigger: my/deployment +``` + +#### Complex `trigger` syntax for multi-project pipelines + +You can configure a branch name that GitLab uses to create +a downstream pipeline with: + +```yaml +rspec: + stage: test + script: bundle exec rspec + +staging: + stage: deploy + trigger: + project: my/deployment + branch: stable +``` + +To mirror the status from a triggered pipeline: + +```yaml +trigger_job: + trigger: + project: my/project + strategy: depend +``` + +To mirror the status from an upstream pipeline: + +```yaml +upstream_bridge: + stage: test + needs: + pipeline: other/project +``` + +#### `trigger` syntax for child pipeline + +> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/16094) in GitLab 12.7. + +To create a [child pipeline](../parent_child_pipelines.md), specify the path to the +YAML file that contains the configuration of the child pipeline: + +```yaml +trigger_job: + trigger: + include: path/to/child-pipeline.yml +``` + +Similar to [multi-project pipelines](../multi_project_pipelines.md#mirror-status-of-a-triggered-pipeline-in-the-trigger-job), +it's possible to mirror the status from a triggered pipeline: + +```yaml +trigger_job: + trigger: + include: + - local: path/to/child-pipeline.yml + strategy: depend +``` + +##### Trigger child pipeline with generated configuration file + +> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/35632) in GitLab 12.9. + +You can also trigger a child pipeline from a [dynamically generated configuration file](../parent_child_pipelines.md#dynamic-child-pipelines): + +```yaml +generate-config: + stage: build + script: generate-ci-config > generated-config.yml + artifacts: + paths: + - generated-config.yml + +child-pipeline: + stage: test + trigger: + include: + - artifact: generated-config.yml + job: generate-config +``` + +The `generated-config.yml` is extracted from the artifacts and used as the configuration +for triggering the child pipeline. + +##### Trigger child pipeline with files from another project + +> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/205157) in GitLab 13.5. + +To trigger child pipelines with files from another private project under the same +GitLab instance, use [`include:file`](#includefile): + +```yaml +child-pipeline: + trigger: + include: + - project: 'my-group/my-pipeline-library' + ref: 'main' + file: '/path/to/child-pipeline.yml' +``` + +#### Linking pipelines with `trigger:strategy` + +By default, the `trigger` job completes with the `success` status +as soon as the downstream pipeline is created. + +To force the `trigger` job to wait for the downstream (multi-project or child) pipeline to complete, use +`strategy: depend`. This setting makes the trigger job wait with a "running" status until the triggered +pipeline completes. At that point, the `trigger` job completes and displays the same status as +the downstream job. + +This setting can help keep your pipeline execution linear. In the following example, jobs from +subsequent stages wait for the triggered pipeline to successfully complete before +starting, which reduces parallelization. + +```yaml +trigger_job: + trigger: + include: path/to/child-pipeline.yml + strategy: depend +``` + +#### Trigger a pipeline by API call + +To force a rebuild of a specific branch, tag, or commit, you can use an API call +with a trigger token. + +The trigger token is different than the [`trigger`](#trigger) keyword. + +[Read more in the triggers documentation.](../triggers/index.md) + +### `interruptible` + +> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/32022) in GitLab 12.3. + +Use `interruptible` to indicate that a running job should be canceled if made redundant by a newer pipeline run. +Defaults to `false` (uninterruptible). Jobs that have not started yet (pending) are considered interruptible +and safe to be cancelled. +This value is used only if the [automatic cancellation of redundant pipelines feature](../pipelines/settings.md#auto-cancel-redundant-pipelines) +is enabled. + +When enabled, a pipeline is immediately canceled when a new pipeline starts on the same branch if either of the following is true: + +- All jobs in the pipeline are set as interruptible. +- Any uninterruptible jobs have not started yet. + +Set jobs as interruptible that can be safely canceled once started (for instance, a build job). + +In the following example, a new pipeline run causes an existing running pipeline to be: + +- Canceled, if only `step-1` is running or pending. +- Not canceled, once `step-2` starts running. + +After an uninterruptible job starts running, the pipeline cannot be canceled. + +```yaml +stages: + - stage1 + - stage2 + - stage3 + +step-1: + stage: stage1 + script: + - echo "Can be canceled." + interruptible: true + +step-2: + stage: stage2 + script: + - echo "Can not be canceled." + +step-3: + stage: stage3 + script: + - echo "Because step-2 can not be canceled, this step can never be canceled, even though it's set as interruptible." + interruptible: true +``` + +### `resource_group` + +> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/15536) in GitLab 12.7. + +Sometimes running multiple jobs or pipelines at the same time in an environment +can lead to errors during the deployment. + +To avoid these errors, use the `resource_group` attribute to make sure that +the runner doesn't run certain jobs simultaneously. Resource groups behave similar +to semaphores in other programming languages. + +When the `resource_group` keyword is defined for a job in the `.gitlab-ci.yml` file, +job executions are mutually exclusive across different pipelines for the same project. +If multiple jobs belonging to the same resource group are enqueued simultaneously, +only one of the jobs is picked by the runner. The other jobs wait until the +`resource_group` is free. + +For example: + +```yaml +deploy-to-production: + script: deploy + resource_group: production +``` + +In this case, two `deploy-to-production` jobs in two separate pipelines can never run at the same time. As a result, +you can ensure that concurrent deployments never happen to the production environment. + +You can define multiple resource groups per environment. For example, +when deploying to physical devices, you may have multiple physical devices. Each device +can be deployed to, but there can be only one deployment per device at any given time. + +The `resource_group` value can only contain letters, digits, `-`, `_`, `/`, `$`, `{`, `}`, `.`, and spaces. +It can't start or end with `/`. + +For more information, see [Deployments Safety](../environments/deployment_safety.md). + +#### Pipeline-level concurrency control with Cross-Project/Parent-Child pipelines + +> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/39057) in GitLab 13.9. + +You can define `resource_group` for downstream pipelines that are sensitive to concurrent +executions. The [`trigger` keyword](#trigger) can trigger downstream pipelines. The +[`resource_group` keyword](#resource_group) can co-exist with it. This is useful to control the +concurrency for deployment pipelines, while running non-sensitive jobs concurrently. + +The following example has two pipeline configurations in a project. When a pipeline starts running, +non-sensitive jobs are executed first and aren't affected by concurrent executions in other +pipelines. However, GitLab ensures that there are no other deployment pipelines running before +triggering a deployment (child) pipeline. If other deployment pipelines are running, GitLab waits +until those pipelines finish before running another one. + +```yaml +# .gitlab-ci.yml (parent pipeline) + +build: + stage: build + script: echo "Building..." + +test: + stage: test + script: echo "Testing..." + +deploy: + stage: deploy + trigger: + include: deploy.gitlab-ci.yml + strategy: depend + resource_group: AWS-production +``` + +```yaml +# deploy.gitlab-ci.yml (child pipeline) + +stages: + - provision + - deploy + +provision: + stage: provision + script: echo "Provisioning..." + +deployment: + stage: deploy + script: echo "Deploying..." +``` + +You must define [`strategy: depend`](#linking-pipelines-with-triggerstrategy) +with the `trigger` keyword. This ensures that the lock isn't released until the downstream pipeline +finishes. + +### `release` + +> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/19298) in GitLab 13.2. + +Use `release` to create a [release](../../user/project/releases/index.md). +Requires the [`release-cli`](https://gitlab.com/gitlab-org/release-cli/-/tree/master/docs) +to be available in your GitLab Runner Docker or shell executor. + +These keywords are supported: + +- [`tag_name`](#releasetag_name) +- [`description`](#releasedescription) +- [`name`](#releasename) (optional) +- [`ref`](#releaseref) (optional) +- [`milestones`](#releasemilestones) (optional) +- [`released_at`](#releasereleased_at) (optional) +- [`assets:links`](#releaseassetslinks) (optional) + +The release is created only if the job processes without error. If the Rails API +returns an error during release creation, the `release` job fails. + +#### `release-cli` Docker image + +You must specify the Docker image to use for the `release-cli`: + +```yaml +image: registry.gitlab.com/gitlab-org/release-cli:latest +``` + +#### `release-cli` for shell executors + +> [Introduced](https://gitlab.com/gitlab-org/release-cli/-/issues/21) in GitLab 13.8. + +For GitLab Runner shell executors, you can download and install the `release-cli` manually for your [supported OS and architecture](https://release-cli-downloads.s3.amazonaws.com/latest/index.html). +Once installed, the `release` keyword should be available to you. + +**Install on Unix/Linux** + +1. Download the binary for your system, in the following example for amd64 systems: + + ```shell + curl --location --output /usr/local/bin/release-cli "https://release-cli-downloads.s3.amazonaws.com/latest/release-cli-linux-amd64" + ``` + +1. Give it permissions to execute: + + ```shell + sudo chmod +x /usr/local/bin/release-cli + ``` + +1. Verify `release-cli` is available: + + ```shell + $ release-cli -v + + release-cli version 0.6.0 + ``` + +**Install on Windows PowerShell** + +1. Create a folder somewhere in your system, for example `C:\GitLab\Release-CLI\bin` + + ```shell + New-Item -Path 'C:\GitLab\Release-CLI\bin' -ItemType Directory + ``` + +1. Download the executable file: + + ```shell + PS C:\> Invoke-WebRequest -Uri "https://release-cli-downloads.s3.amazonaws.com/latest/release-cli-windows-amd64.exe" -OutFile "C:\GitLab\Release-CLI\bin\release-cli.exe" + + Directory: C:\GitLab\Release-CLI + Mode LastWriteTime Length Name + ---- ------------- ------ ---- + d----- 3/16/2021 4:17 AM bin + + ``` + +1. Add the directory to your `$env:PATH`: + + ```shell + $env:PATH += ";C:\GitLab\Release-CLI\bin" + ``` + +1. Verify `release-cli` is available: + + ```shell + PS C:\> release-cli -v + + release-cli version 0.6.0 + ``` + +#### Use a custom SSL CA certificate authority + +You can use the `ADDITIONAL_CA_CERT_BUNDLE` CI/CD variable to configure a custom SSL CA certificate authority, +which is used to verify the peer when the `release-cli` creates a release through the API using HTTPS with custom certificates. +The `ADDITIONAL_CA_CERT_BUNDLE` value should contain the +[text representation of the X.509 PEM public-key certificate](https://tools.ietf.org/html/rfc7468#section-5.1) +or the `path/to/file` containing the certificate authority. +For example, to configure this value in the `.gitlab-ci.yml` file, use the following: + +```yaml +release: + variables: + ADDITIONAL_CA_CERT_BUNDLE: | + -----BEGIN CERTIFICATE----- + MIIGqTCCBJGgAwIBAgIQI7AVxxVwg2kch4d56XNdDjANBgkqhkiG9w0BAQsFADCB + ... + jWgmPqF3vUbZE0EyScetPJquRFRKIesyJuBFMAs= + -----END CERTIFICATE----- + script: + - echo "Create release" + release: + name: 'My awesome release' + tag_name: '$CI_COMMIT_TAG' +``` + +The `ADDITIONAL_CA_CERT_BUNDLE` value can also be configured as a +[custom variable in the UI](../variables/index.md#custom-cicd-variables), +either as a `file`, which requires the path to the certificate, or as a variable, +which requires the text representation of the certificate. + +#### `script` + +All jobs except [trigger](#trigger) jobs must have the `script` keyword. A `release` +job can use the output from script commands, but you can use a placeholder script if +the script is not needed: + +```yaml +script: + - echo 'release job' +``` + +An [issue](https://gitlab.com/gitlab-org/gitlab/-/issues/223856) exists to remove this requirement in an upcoming version of GitLab. + +A pipeline can have multiple `release` jobs, for example: + +```yaml +ios-release: + script: + - echo 'iOS release job' + release: + tag_name: v1.0.0-ios + description: 'iOS release v1.0.0' + +android-release: + script: + - echo 'Android release job' + release: + tag_name: v1.0.0-android + description: 'Android release v1.0.0' +``` + +#### `release:tag_name` + +You must specify a `tag_name` for the release. The tag can refer to an existing Git tag or +you can specify a new tag. + +When the specified tag doesn't exist in the repository, a new tag is created from the associated SHA of the pipeline. + +For example, when creating a release from a Git tag: + +```yaml +job: + release: + tag_name: $CI_COMMIT_TAG + description: 'Release description' +``` + +It is also possible for the release job to automatically create a new unique tag. In that case, +do not use [`rules`](#rules) or [`only`](#only--except) to configure the job to +only run for tags. + +A semantic versioning example: + +```yaml +job: + release: + tag_name: ${MAJOR}_${MINOR}_${REVISION} + description: 'Release description' +``` + +- The release is created only if the job's main script succeeds. +- If the release already exists, it is not updated and the job with the `release` keyword fails. +- The `release` section executes after the `script` tag and before the `after_script`. + +#### `release:name` + +The release name. If omitted, it is populated with the value of `release: tag_name`. + +#### `release:description` + +Specifies the long description of the release. You can also specify a file that contains the +description. + +##### Read description from a file + +> [Introduced](https://gitlab.com/gitlab-org/release-cli/-/merge_requests/67) in GitLab 13.7. + +You can specify a file in `$CI_PROJECT_DIR` that contains the description. The file must be relative +to the project directory (`$CI_PROJECT_DIR`), and if the file is a symbolic link it can't reside +outside of `$CI_PROJECT_DIR`. The `./path/to/file` and filename can't contain spaces. + +```yaml +job: + release: + tag_name: ${MAJOR}_${MINOR}_${REVISION} + description: './path/to/CHANGELOG.md' +``` + +#### `release:ref` + +If the `release: tag_name` doesn't exist yet, the release is created from `ref`. +`ref` can be a commit SHA, another tag name, or a branch name. + +#### `release:milestones` + +The title of each milestone the release is associated with. + +#### `release:released_at` + +The date and time when the release is ready. Defaults to the current date and time if not +defined. Should be enclosed in quotes and expressed in ISO 8601 format. + +```json +released_at: '2021-03-15T08:00:00Z' +``` + +#### `release:assets:links` + +> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/271454) in GitLab 13.12. + +Include [asset links](../../user/project/releases/index.md#release-assets) in the release. + +NOTE: +Requires `release-cli` version v0.4.0 or higher. + +```yaml +assets: + links: + - name: 'asset1' + url: 'https://example.com/assets/1' + - name: 'asset2' + url: 'https://example.com/assets/2' + filepath: '/pretty/url/1' # optional + link_type: 'other' # optional +``` + +#### Complete example for `release` + +If you combine the previous examples for `release`, you get two options, depending on how you generate the +tags. You can't use these options together, so choose one: + +- To create a release when you push a Git tag, or when you add a Git tag + in the UI by going to **Repository > Tags**: + + ```yaml + release_job: + stage: release + image: registry.gitlab.com/gitlab-org/release-cli:latest + rules: + - if: $CI_COMMIT_TAG # Run this job when a tag is created manually + script: + - echo 'running release_job' + release: + name: 'Release $CI_COMMIT_TAG' + description: 'Created using the release-cli $EXTRA_DESCRIPTION' # $EXTRA_DESCRIPTION must be defined + tag_name: '$CI_COMMIT_TAG' # elsewhere in the pipeline. + ref: '$CI_COMMIT_TAG' + milestones: + - 'm1' + - 'm2' + - 'm3' + released_at: '2020-07-15T08:00:00Z' # Optional, is auto generated if not defined, or can use a variable. + assets: # Optional, multiple asset links + links: + - name: 'asset1' + url: 'https://example.com/assets/1' + - name: 'asset2' + url: 'https://example.com/assets/2' + filepath: '/pretty/url/1' # optional + link_type: 'other' # optional + ``` + +- To create a release automatically when commits are pushed or merged to the default branch, + using a new Git tag that is defined with variables: + + NOTE: + Environment variables set in `before_script` or `script` are not available for expanding + in the same job. Read more about + [potentially making variables available for expanding](https://gitlab.com/gitlab-org/gitlab-runner/-/issues/6400). + + ```yaml + prepare_job: + stage: prepare # This stage must run before the release stage + rules: + - if: $CI_COMMIT_TAG + when: never # Do not run this job when a tag is created manually + - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH # Run this job when commits are pushed or merged to the default branch + script: + - echo "EXTRA_DESCRIPTION=some message" >> variables.env # Generate the EXTRA_DESCRIPTION and TAG environment variables + - echo "TAG=v$(cat VERSION)" >> variables.env # and append to the variables.env file + artifacts: + reports: + dotenv: variables.env # Use artifacts:reports:dotenv to expose the variables to other jobs + + release_job: + stage: release + image: registry.gitlab.com/gitlab-org/release-cli:latest + needs: + - job: prepare_job + artifacts: true + rules: + - if: $CI_COMMIT_TAG + when: never # Do not run this job when a tag is created manually + - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH # Run this job when commits are pushed or merged to the default branch + script: + - echo 'running release_job for $TAG' + release: + name: 'Release $TAG' + description: 'Created using the release-cli $EXTRA_DESCRIPTION' # $EXTRA_DESCRIPTION and the $TAG + tag_name: '$TAG' # variables must be defined elsewhere + ref: '$CI_COMMIT_SHA' # in the pipeline. For example, in the + milestones: # prepare_job + - 'm1' + - 'm2' + - 'm3' + released_at: '2020-07-15T08:00:00Z' # Optional, is auto generated if not defined, or can use a variable. + assets: + links: + - name: 'asset1' + url: 'https://example.com/assets/1' + - name: 'asset2' + url: 'https://example.com/assets/2' + filepath: '/pretty/url/1' # optional + link_type: 'other' # optional + ``` + +#### Release assets as Generic packages + +You can use [Generic packages](../../user/packages/generic_packages/) to host your release assets. +For a complete example, see the [Release assets as Generic packages](https://gitlab.com/gitlab-org/release-cli/-/tree/master/docs/examples/release-assets-as-generic-package/) +project. + +#### `release-cli` command line + +The entries under the `release` node are transformed into a `bash` command line and sent +to the Docker container, which contains the [release-cli](https://gitlab.com/gitlab-org/release-cli). +You can also call the `release-cli` directly from a `script` entry. + +For example, if you use the YAML described previously: + +```shell +release-cli create --name "Release $CI_COMMIT_SHA" --description "Created using the release-cli $EXTRA_DESCRIPTION" --tag-name "v${MAJOR}.${MINOR}.${REVISION}" --ref "$CI_COMMIT_SHA" --released-at "2020-07-15T08:00:00Z" --milestone "m1" --milestone "m2" --milestone "m3" --assets-link "{\"name\":\"asset1\",\"url\":\"https://example.com/assets/1\",\"link_type\":\"other\"} +``` + +### `secrets` + +> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/33014) in GitLab 13.4. + +Use `secrets` to specify the [CI/CD Secrets](../secrets/index.md) the job needs. It should be a hash, +and the keys should be the names of the variables that are made available to the job. +The value of each secret is saved in a temporary file. This file's path is stored in these +variables. + +#### `secrets:vault` **(PREMIUM)** + +> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/28321) in GitLab 13.4. + +Use `vault` to specify secrets provided by [Hashicorp's Vault](https://www.vaultproject.io/). + +This syntax has multiple forms. The shortest form assumes the use of the +[KV-V2](https://www.vaultproject.io/docs/secrets/kv/kv-v2) secrets engine, +mounted at the default path `kv-v2`. The last part of the secret's path is the +field to fetch the value for: + +```yaml +job: + secrets: + DATABASE_PASSWORD: + vault: production/db/password # translates to secret `kv-v2/data/production/db`, field `password` +``` + +You can specify a custom secrets engine path by adding a suffix starting with `@`: + +```yaml +job: + secrets: + DATABASE_PASSWORD: + vault: production/db/password@ops # translates to secret `ops/data/production/db`, field `password` +``` + +In the detailed form of the syntax, you can specify all details explicitly: + +```yaml +job: + secrets: + DATABASE_PASSWORD: # translates to secret `ops/data/production/db`, field `password` + vault: + engine: + name: kv-v2 + path: ops + path: production/db + field: password +``` + +### `pages` + +Use `pages` to upload static content to GitLab. The content +is then published as a website. You must: + +- Place any static content in a `public/` directory. +- Define [`artifacts`](#artifacts) with a path to the `public/` directory. + +The following example moves all files from the root of the project to the +`public/` directory. The `.public` workaround is so `cp` does not also copy +`public/` to itself in an infinite loop: + +```yaml +pages: + stage: deploy + script: + - mkdir .public + - cp -r * .public + - mv .public public + artifacts: + paths: + - public + rules: + - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH +``` + +View the [GitLab Pages user documentation](../../user/project/pages/index.md). + +### `inherit` + +> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/207484) in GitLab 12.9. + +Use `inherit:` to control inheritance of globally-defined defaults +and variables. + +To enable or disable the inheritance of all `default:` or `variables:` keywords, use: + +- `default: true` or `default: false` +- `variables: true` or `variables: false` + +To inherit only a subset of `default:` keywords or `variables:`, specify what +you wish to inherit. Anything not listed is **not** inherited. Use +one of the following formats: + +```yaml +inherit: + default: [keyword1, keyword2] + variables: [VARIABLE1, VARIABLE2] +``` + +Or: + +```yaml +inherit: + default: + - keyword1 + - keyword2 + variables: + - VARIABLE1 + - VARIABLE2 +``` + +In the following example: + +- `rubocop`: + - inherits: Nothing. +- `rspec`: + - inherits: the default `image` and the `WEBHOOK_URL` variable. + - does **not** inherit: the default `before_script` and the `DOMAIN` variable. +- `capybara`: + - inherits: the default `before_script` and `image`. + - does **not** inherit: the `DOMAIN` and `WEBHOOK_URL` variables. +- `karma`: + - inherits: the default `image` and `before_script`, and the `DOMAIN` variable. + - does **not** inherit: `WEBHOOK_URL` variable. + +```yaml +default: + image: 'ruby:2.4' + before_script: + - echo Hello World + +variables: + DOMAIN: example.com + WEBHOOK_URL: https://my-webhook.example.com + +rubocop: + inherit: + default: false + variables: false + script: bundle exec rubocop + +rspec: + inherit: + default: [image] + variables: [WEBHOOK_URL] + script: bundle exec rspec + +capybara: + inherit: + variables: false + script: bundle exec capybara + +karma: + inherit: + default: true + variables: [DOMAIN] + script: karma +``` + +## `variables` + +> Introduced in GitLab Runner v0.5.0. + +[CI/CD variables](../variables/index.md) are configurable values that are passed to jobs. +They can be set globally and per-job. + +There are two types of variables. + +- [Custom variables](../variables/index.md#custom-cicd-variables): + You can define their values in the `.gitlab-ci.yml` file, in the GitLab UI, + or by using the API. You can also input variables in the GitLab UI when + [running a pipeline manually](../pipelines/index.md#run-a-pipeline-manually). +- [Predefined variables](../variables/predefined_variables.md): + These values are set by the runner itself. + One example is `CI_COMMIT_REF_NAME`, which is the branch or tag the project is built for. + +After you define a variable, you can use it in all executed commands and scripts. + +Variables are meant for non-sensitive project configuration, for example: + +```yaml +variables: + DEPLOY_SITE: "https://example.com/" + +deploy_job: + stage: deploy + script: + - deploy-script --url $DEPLOY_SITE --path "/" + +deploy_review_job: + stage: deploy + variables: + REVIEW_PATH: "/review" + script: + - deploy-review-script --url $DEPLOY_SITE --path $REVIEW_PATH +``` + +You can use only integers and strings for the variable's name and value. + +If you define a variable at the top level of the `gitlab-ci.yml` file, it is global, +meaning it applies to all jobs. If you define a variable in a job, it's available +to that job only. + +If a variable of the same name is defined globally and for a specific job, the +[job-specific variable overrides the global variable](../variables/index.md#cicd-variable-precedence). + +All YAML-defined variables are also set to any linked +[Docker service containers](../services/index.md). + +You can use [YAML anchors for variables](#yaml-anchors-for-variables). + +### Prefill variables in manual pipelines + +> [Introduced in](https://gitlab.com/gitlab-org/gitlab/-/issues/30101) GitLab 13.7. + +Use the `value` and `description` keywords to define [pipeline-level (global) variables that are prefilled](../pipelines/index.md#prefill-variables-in-manual-pipelines) +when [running a pipeline manually](../pipelines/index.md#run-a-pipeline-manually): + +```yaml +variables: + DEPLOY_ENVIRONMENT: + value: "staging" # Deploy to staging by default + description: "The deployment target. Change this variable to 'canary' or 'production' if needed." +``` + +You cannot set job-level variables to be pre-filled when you run a pipeline manually. + +### Configure runner behavior with variables + +You can use [CI/CD variables](../variables/index.md) to configure how the runner processes Git requests: + +- [`GIT_STRATEGY`](../runners/configure_runners.md#git-strategy) +- [`GIT_SUBMODULE_STRATEGY`](../runners/configure_runners.md#git-submodule-strategy) +- [`GIT_CHECKOUT`](../runners/configure_runners.md#git-checkout) +- [`GIT_CLEAN_FLAGS`](../runners/configure_runners.md#git-clean-flags) +- [`GIT_FETCH_EXTRA_FLAGS`](../runners/configure_runners.md#git-fetch-extra-flags) +- [`GIT_DEPTH`](../runners/configure_runners.md#shallow-cloning) (shallow cloning) +- [`GIT_CLONE_PATH`](../runners/configure_runners.md#custom-build-directories) (custom build directories) +- [`TRANSFER_METER_FREQUENCY`](../runners/configure_runners.md#artifact-and-cache-settings) (artifact/cache meter update frequency) +- [`ARTIFACT_COMPRESSION_LEVEL`](../runners/configure_runners.md#artifact-and-cache-settings) (artifact archiver compression level) +- [`CACHE_COMPRESSION_LEVEL`](../runners/configure_runners.md#artifact-and-cache-settings) (cache archiver compression level) + +You can also use variables to configure how many times a runner +[attempts certain stages of job execution](../runners/configure_runners.md#job-stages-attempts). + +## YAML-specific features + +In your `.gitlab-ci.yml` file, you can use YAML-specific features like anchors (`&`), aliases (`*`), +and map merging (`<<`). Use these features to reduce the complexity +of the code in the `.gitlab-ci.yml` file. + +Read more about the various [YAML features](https://learnxinyminutes.com/docs/yaml/). + +In most cases, the [`extends` keyword](#extends) is more user friendly and you should +use it when possible. + +You can use YAML anchors to merge YAML arrays. + +### Anchors + +YAML has a feature called 'anchors' that you can use to duplicate +content across your document. + +Use anchors to duplicate or inherit properties. Use anchors with [hidden jobs](#hide-jobs) +to provide templates for your jobs. When there are duplicate keys, GitLab +performs a reverse deep merge based on the keys. + +You can't use YAML anchors across multiple files when using the [`include`](#include) +keyword. Anchors are only valid in the file they were defined in. To reuse configuration +from different YAML files, use [`!reference` tags](#reference-tags) or the +[`extends` keyword](#extends). + +The following example uses anchors and map merging. It creates two jobs, +`test1` and `test2`, that inherit the `.job_template` configuration, each +with their own custom `script` defined: + +```yaml +.job_template: &job_configuration # Hidden yaml configuration that defines an anchor named 'job_configuration' + image: ruby:2.6 + services: + - postgres + - redis + +test1: + <<: *job_configuration # Merge the contents of the 'job_configuration' alias + script: + - test1 project + +test2: + <<: *job_configuration # Merge the contents of the 'job_configuration' alias + script: + - test2 project +``` + +`&` sets up the name of the anchor (`job_configuration`), `<<` means "merge the +given hash into the current one," and `*` includes the named anchor +(`job_configuration` again). The expanded version of this example is: + +```yaml +.job_template: + image: ruby:2.6 + services: + - postgres + - redis + +test1: + image: ruby:2.6 + services: + - postgres + - redis + script: + - test1 project + +test2: + image: ruby:2.6 + services: + - postgres + - redis + script: + - test2 project +``` + +You can use anchors to define two sets of services. For example, `test:postgres` +and `test:mysql` share the `script` defined in `.job_template`, but use different +`services`, defined in `.postgres_services` and `.mysql_services`: + +```yaml +.job_template: &job_configuration + script: + - test project + tags: + - dev + +.postgres_services: + services: &postgres_configuration + - postgres + - ruby + +.mysql_services: + services: &mysql_configuration + - mysql + - ruby + +test:postgres: + <<: *job_configuration + services: *postgres_configuration + tags: + - postgres + +test:mysql: + <<: *job_configuration + services: *mysql_configuration +``` + +The expanded version is: + +```yaml +.job_template: + script: + - test project + tags: + - dev + +.postgres_services: + services: + - postgres + - ruby + +.mysql_services: + services: + - mysql + - ruby + +test:postgres: + script: + - test project + services: + - postgres + - ruby + tags: + - postgres + +test:mysql: + script: + - test project + services: + - mysql + - ruby + tags: + - dev +``` + +You can see that the hidden jobs are conveniently used as templates, and +`tags: [postgres]` overwrites `tags: [dev]`. + +#### YAML anchors for scripts + +> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/23005) in GitLab 12.5. + +You can use [YAML anchors](#anchors) with [script](#script), [`before_script`](#before_script), +and [`after_script`](#after_script) to use predefined commands in multiple jobs: + +```yaml +.some-script-before: &some-script-before + - echo "Execute this script first" + +.some-script: &some-script + - echo "Execute this script second" + - echo "Execute this script too" + +.some-script-after: &some-script-after + - echo "Execute this script last" + +job1: + before_script: + - *some-script-before + script: + - *some-script + - echo "Execute something, for this job only" + after_script: + - *some-script-after + +job2: + script: + - *some-script-before + - *some-script + - echo "Execute something else, for this job only" + - *some-script-after +``` + +#### YAML anchors for variables + +Use [YAML anchors](#anchors) with `variables` to repeat assignment +of variables across multiple jobs. You can also use YAML anchors when a job +requires a specific `variables` block that would otherwise override the global variables. + +The following example shows how override the `GIT_STRATEGY` variable without affecting +the use of the `SAMPLE_VARIABLE` variable: + +```yaml +# global variables +variables: &global-variables + SAMPLE_VARIABLE: sample_variable_value + ANOTHER_SAMPLE_VARIABLE: another_sample_variable_value + +# a job that must set the GIT_STRATEGY variable, yet depend on global variables +job_no_git_strategy: + stage: cleanup + variables: + <<: *global-variables + GIT_STRATEGY: none + script: echo $SAMPLE_VARIABLE +``` + +### Hide jobs + +If you want to temporarily disable a job, rather than commenting out all the +lines where the job is defined: + +```yaml +# hidden_job: +# script: +# - run test +``` + +Instead, you can start its name with a dot (`.`) and it is not processed by +GitLab CI/CD. In the following example, `.hidden_job` is ignored: + +```yaml +.hidden_job: + script: + - run test +``` + +Use this feature to ignore jobs, or use the +[YAML-specific features](#yaml-specific-features) and transform the hidden jobs +into templates. + +### `!reference` tags + +> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/266173) in GitLab 13.9. + +Use the `!reference` custom YAML tag to select keyword configuration from other job +sections and reuse it in the current section. Unlike [YAML anchors](#anchors), you can +use `!reference` tags to reuse configuration from [included](#include) configuration +files as well. + +In the following example, a `script` and an `after_script` from two different locations are +reused in the `test` job: + +- `setup.yml`: + + ```yaml + .setup: + script: + - echo creating environment + ``` + +- `.gitlab-ci.yml`: + + ```yaml + include: + - local: setup.yml + + .teardown: + after_script: + - echo deleting environment + + test: + script: + - !reference [.setup, script] + - echo running my own command + after_script: + - !reference [.teardown, after_script] + ``` + +In the following example, `test-vars-1` reuses all the variables in `.vars`, while `test-vars-2` +selects a specific variable and reuses it as a new `MY_VAR` variable. + +```yaml +.vars: + variables: + URL: "http://my-url.internal" + IMPORTANT_VAR: "the details" + +test-vars-1: + variables: !reference [.vars, variables] + script: + - printenv + +test-vars-2: + variables: + MY_VAR: !reference [.vars, variables, IMPORTANT_VAR] + script: + - printenv +``` + +You can't reuse a section that already includes a `!reference` tag. Only one level +of nesting is supported. + +## Skip Pipeline + +To push a commit without triggering a pipeline, add `[ci skip]` or `[skip ci]`, using any +capitalization, to your commit message. + +Alternatively, if you are using Git 2.10 or later, use the `ci.skip` [Git push option](../../user/project/push_options.md#push-options-for-gitlab-cicd). +The `ci.skip` push option does not skip merge request +pipelines. + +## Processing Git pushes + +GitLab creates at most four branch and tag pipelines when +pushing multiple changes in a single `git push` invocation. + +This limitation does not affect any of the updated merge request pipelines. +All updated merge requests have a pipeline created when using +[pipelines for merge requests](../merge_request_pipelines/index.md). + +## Deprecated keywords + +The following keywords are deprecated. + +### Globally-defined `types` + +WARNING: +`types` is deprecated, and could be removed in a future release. +Use [`stages`](#stages) instead. + +### Job-defined `type` + +WARNING: +`type` is deprecated, and could be removed in one of the future releases. +Use [`stage`](#stage) instead. + +### Globally-defined `image`, `services`, `cache`, `before_script`, `after_script` + +Defining `image`, `services`, `cache`, `before_script`, and +`after_script` globally is deprecated. Support could be removed +from a future release. + +Use [`default:`](#custom-default-keyword-values) instead. For example: + +```yaml +default: + image: ruby:3.0 + services: + - docker:dind + cache: + paths: [vendor/] + before_script: + - bundle config set path vendor/bundle + - bundle install + after_script: + - rm -rf tmp/ +``` + + diff --git a/doc/ci/yaml/script.md b/doc/ci/yaml/script.md index fb0ad07484c..9e118895d7c 100644 --- a/doc/ci/yaml/script.md +++ b/doc/ci/yaml/script.md @@ -7,7 +7,7 @@ type: reference # GitLab CI/CD script syntax **(FREE)** -You can use special syntax in [`script`](README.md#script) sections to: +You can use special syntax in [`script`](index.md#script) sections to: - [Split long commands](#split-long-commands) into multiline commands. - [Use color codes](#add-color-codes-to-script-output) to make job logs easier to review. diff --git a/doc/development/auto_devops.md b/doc/development/auto_devops.md index 054a3439ef1..2989e10a124 100644 --- a/doc/development/auto_devops.md +++ b/doc/development/auto_devops.md @@ -18,7 +18,7 @@ is also available on YouTube. Auto DevOps builds on top of GitLab CI/CD to create an automatic pipeline based on your project contents. When Auto DevOps is enabled for a project, the user does not need to explicitly include any pipeline configuration -through a [`.gitlab-ci.yml` file](../ci/yaml/README.md). +through a [`.gitlab-ci.yml` file](../ci/yaml/index.md). In the absence of a `.gitlab-ci.yml` file, the [Auto DevOps CI template](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Auto-DevOps.gitlab-ci.yml) diff --git a/doc/development/cicd/cicd_reference_documentation_guide.md b/doc/development/cicd/cicd_reference_documentation_guide.md index a6e4c3f8de8..33bc416d8bc 100644 --- a/doc/development/cicd/cicd_reference_documentation_guide.md +++ b/doc/development/cicd/cicd_reference_documentation_guide.md @@ -91,7 +91,7 @@ Keyword description and main details. ### YAML reference style example -See the [`only:changes` / `except:changes`](../../ci/yaml/README.md#onlychanges--exceptchanges) +See the [`only:changes` / `except:changes`](../../ci/yaml/index.md#onlychanges--exceptchanges) documentation for an example of the YAML reference style. The following example is a shortened version of that documentation's Markdown: diff --git a/doc/development/cicd/index.md b/doc/development/cicd/index.md index 64a3c74db62..56f511cfcff 100644 --- a/doc/development/cicd/index.md +++ b/doc/development/cicd/index.md @@ -12,7 +12,7 @@ Development guides that are specific to CI/CD are listed here. If you are creating new CI/CD templates, please read [the development guide for GitLab CI/CD templates](templates.md). See the [CI/CD YAML reference documentation guide](cicd_reference_documentation_guide.md) -to learn how to update the [reference page](../../ci/yaml/README.md). +to learn how to update the [reference page](../../ci/yaml/index.md). ## CI Architecture overview @@ -33,7 +33,7 @@ On the left side we have the events that can trigger a pipeline based on various - When project is [subscribed to an upstream project](../../ci/multi_project_pipelines.md#trigger-a-pipeline-when-an-upstream-project-is-rebuilt). - When [Auto DevOps](../../topics/autodevops/index.md) is enabled. - When GitHub integration is used with [external pull requests](../../ci/ci_cd_for_external_repos/index.md#pipelines-for-external-pull-requests). -- When an upstream pipeline contains a [bridge job](../../ci/yaml/README.md#trigger) which triggers a downstream pipeline. +- When an upstream pipeline contains a [bridge job](../../ci/yaml/index.md#trigger) which triggers a downstream pipeline. Triggering any of these events invokes the [`CreatePipelineService`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/app/services/ci/create_pipeline_service.rb) which takes as input event data and the user triggering it, then attempts to create a pipeline. @@ -42,7 +42,7 @@ The `CreatePipelineService` relies heavily on the [`YAML Processor`](https://git component, which is responsible for taking in a YAML blob as input and returns the abstract data structure of a pipeline (including stages and all jobs). This component also validates the structure of the YAML while processing it, and returns any syntax or semantic errors. The `YAML Processor` component is where we define -[all the keywords](../../ci/yaml/README.md) available to structure a pipeline. +[all the keywords](../../ci/yaml/index.md) available to structure a pipeline. The `CreatePipelineService` receives the abstract data structure returned by the `YAML Processor`, which then converts it to persisted models (pipeline, stages, jobs, etc.). After that, the pipeline is ready @@ -79,12 +79,12 @@ case the runner downloads them using a dedicated API endpoint. Artifacts are stored in object storage, while metadata is kept in the database. An important example of artifacts are reports (JUnit, SAST, DAST, etc.) which are parsed and rendered in the merge request. -Job status transitions are not all automated. A user may run [manual jobs](../../ci/yaml/README.md#whenmanual), cancel a pipeline, retry +Job status transitions are not all automated. A user may run [manual jobs](../../ci/yaml/index.md#whenmanual), cancel a pipeline, retry specific failed jobs or the entire pipeline. Anything that causes a job to change status triggers `ProcessPipelineService`, as it's responsible for tracking the status of the entire pipeline. -A special type of job is the [bridge job](../../ci/yaml/README.md#trigger) which is executed server-side +A special type of job is the [bridge job](../../ci/yaml/index.md#trigger) which is executed server-side when transitioning to the `pending` state. This job is responsible for creating a downstream pipeline, such as a multi-project or child pipeline. The workflow loop starts again from the `CreatePipelineService` every time a downstream pipeline is triggered. diff --git a/doc/development/cicd/templates.md b/doc/development/cicd/templates.md index eddaabe41d8..204287d7b59 100644 --- a/doc/development/cicd/templates.md +++ b/doc/development/cicd/templates.md @@ -16,7 +16,7 @@ Before submitting a merge request with a new or updated CI/CD template, you must - Place the template in the correct [directory](#template-directories). - Follow the [CI/CD template authoring guidelines](#template-authoring-guidelines). - Name the template following the `*.gitlab-ci.yml` format. -- Use valid [`.gitlab-ci.yml` syntax](../../ci/yaml/README.md). Verify it's valid +- Use valid [`.gitlab-ci.yml` syntax](../../ci/yaml/index.md). Verify it's valid with the [CI/CD lint tool](../../ci/lint.md). - Include [a changelog](../changelog.md) if the merge request introduces a user-facing change. - Follow the [template review process](#contribute-cicd-template-merge-requests). @@ -59,8 +59,8 @@ don't have any other `.gitlab-ci.yml` files. When authoring pipeline templates: -- Place any [global keywords](../../ci/yaml/README.md#global-keywords) like `image` - or `before_script` in a [`default`](../../ci/yaml/README.md#custom-default-keyword-values) +- Place any [global keywords](../../ci/yaml/index.md#global-keywords) like `image` + or `before_script` in a [`default`](../../ci/yaml/index.md#custom-default-keyword-values) section at the top of the template. - Note clearly in the [code comments](#explain-the-template-with-comments) if the template is designed to be used with the `includes` keyword in an existing @@ -68,7 +68,7 @@ When authoring pipeline templates: A **job template** provides specific jobs that can be added to an existing CI/CD workflow to accomplish specific tasks. It usually should be used by adding it to -an existing `.gitlab-ci.yml` file by using the [`includes`](../../ci/yaml/README.md#global-keywords) +an existing `.gitlab-ci.yml` file by using the [`includes`](../../ci/yaml/index.md#global-keywords) keyword. You can also copy and paste the contents into an existing `.gitlab-ci.yml` file. Configure job templates so that users can add them to their current pipeline with very @@ -77,7 +77,7 @@ other pipeline configuration. When authoring job templates: -- Do not use [global](../../ci/yaml/README.md#global-keywords) or [`default`](../../ci/yaml/README.md#custom-default-keyword-values) +- Do not use [global](../../ci/yaml/index.md#global-keywords) or [`default`](../../ci/yaml/index.md#custom-default-keyword-values) keywords. When a root `.gitlab-ci.yml` includes a template, global or default keywords might be overridden and cause unexpected behavior. If a job template requires a specific stage, explain in the code comments that users must manually add the stage @@ -127,8 +127,8 @@ job2: #### Use `rules` instead of `only` or `except` -Avoid using [`only` or `except`](../../ci/yaml/README.md#only--except) if possible. -Only and except is not being developed any more, and [`rules`](../../ci/yaml/README.md#rules) +Avoid using [`only` or `except`](../../ci/yaml/index.md#only--except) if possible. +Only and except is not being developed any more, and [`rules`](../../ci/yaml/index.md#rules) is now the preferred syntax: ```yaml diff --git a/doc/development/database/multiple_databases.md b/doc/development/database/multiple_databases.md new file mode 100644 index 00000000000..dbc8ab0f215 --- /dev/null +++ b/doc/development/database/multiple_databases.md @@ -0,0 +1,104 @@ +--- +stage: Enablement +group: Sharding +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 +--- + +# Multiple Databases + +In order to scale GitLab, the GitLab application database +will be [decomposed into multiple +databases](https://gitlab.com/groups/gitlab-org/-/epics/6168). + +## CI Database + +Support for configuring the GitLab Rails application to use a distinct +database for CI tables was added in [GitLab +14.1](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/64289). This +feature is still under development, and is not ready for production use. + +By default, GitLab is configured to use only one main database. To +opt-in to use a main database, and CI database, modify the +`config/database.yml` file to have a `primary` and a `ci` database +configurations. For example, given a `config/database.yml` like below: + +```yaml +development: + adapter: postgresql + encoding: unicode + database: gitlabhq_development + host: /path/to/gdk/postgresql + pool: 10 + prepared_statements: false + variables: + statement_timeout: 120s + +test: &test + adapter: postgresql + encoding: unicode + database: gitlabhq_test + host: /path/to/gdk/postgresql + pool: 10 + prepared_statements: false + variables: + statement_timeout: 120s +``` + +Edit the `config/database.yml` to look like this: + +```yaml +development: + primary: + adapter: postgresql + encoding: unicode + database: gitlabhq_development + host: /path/to/gdk/postgresql + pool: 10 + prepared_statements: false + variables: + statement_timeout: 120s + ci: + adapter: postgresql + encoding: unicode + database: gitlabhq_development_ci + migrations_paths: db/ci_migrate + host: /path/to/gdk/postgresql + pool: 10 + prepared_statements: false + variables: + statement_timeout: 120s + +test: &test + primary: + adapter: postgresql + encoding: unicode + database: gitlabhq_test + host: /path/to/gdk/postgresql + pool: 10 + prepared_statements: false + variables: + statement_timeout: 120s + ci: + adapter: postgresql + encoding: unicode + database: gitlabhq_test_ci + migrations_paths: db/ci_migrate + host: /path/to/gdk/postgresql + pool: 10 + prepared_statements: false + variables: + statement_timeout: 120s +``` + +Note that we use `primary` in the `config/database.yml` to refer to the main +database. This is to match the default name Rails has. + +### Migrations + +Any migrations that affect `Ci::ApplicationRecord` models +and their tables must be placed in two directories for now: + +- `db/migrate` +- `db/ci_migrate` + +We aim to keep the schema for both tables the same across both databases. diff --git a/doc/development/documentation/index.md b/doc/development/documentation/index.md index 14798b747c8..b2ac48db7fb 100644 --- a/doc/development/documentation/index.md +++ b/doc/development/documentation/index.md @@ -123,7 +123,7 @@ following: - `tutorial`: Learn a process/concept by doing. [Example page](../../gitlab-basics/start-using-git.md). - `reference`: A collection of information used as a reference to use a feature - or a functionality. [Example page](../../ci/yaml/README.md). + or a functionality. [Example page](../../ci/yaml/index.md). ### Redirection metadata @@ -475,10 +475,10 @@ If you want to know the in-depth details, here's what's really happening: The following GitLab features are used among others: -- [Manual actions](../../ci/yaml/README.md#whenmanual) +- [Manual actions](../../ci/yaml/index.md#whenmanual) - [Multi project pipelines](../../ci/multi_project_pipelines.md) - [Review Apps](../../ci/review_apps/index.md) -- [Artifacts](../../ci/yaml/README.md#artifacts) +- [Artifacts](../../ci/yaml/index.md#artifacts) - [Specific runner](../../ci/runners/runners_scope.md#prevent-a-specific-runner-from-being-enabled-for-other-projects) - [Pipelines for merge requests](../../ci/merge_request_pipelines/index.md) diff --git a/doc/development/integrations/secure.md b/doc/development/integrations/secure.md index d48bdbc7be6..7c178a4c84a 100644 --- a/doc/development/integrations/secure.md +++ b/doc/development/integrations/secure.md @@ -7,7 +7,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w # Security scanner integration Integrating a security scanner into GitLab consists of providing end users -with a [CI job definition](../../ci/yaml/README.md) +with a [CI job definition](../../ci/yaml/index.md) they can add to their CI configuration files to scan their GitLab projects. This CI job should then output its results in a GitLab-specified format. These results are then automatically presented in various places in GitLab, such as the Pipeline view, Merge Request @@ -23,7 +23,7 @@ scanner, as well as requirements and guidelines for the Docker image. This section describes several important fields to add to the security scanner's job definition file. Full documentation on these and other available fields can be viewed -in the [CI documentation](../../ci/yaml/README.md#image). +in the [CI documentation](../../ci/yaml/index.md#image). ### Name @@ -34,41 +34,41 @@ For instance, the dependency scanning job based on the "MySec" scanner would be ### Image -The [`image`](../../ci/yaml/README.md#image) keyword is used to specify +The [`image`](../../ci/yaml/index.md#image) keyword is used to specify the [Docker image](../../ci/docker/using_docker_images.md#what-is-an-image) containing the security scanner. ### Script -The [`script`](../../ci/yaml/README.md#script) keyword +The [`script`](../../ci/yaml/index.md#script) keyword is used to specify the commands to run the scanner. Because the `script` entry can't be left empty, it must be set to the command that performs the scan. It is not possible to rely on the predefined `ENTRYPOINT` and `CMD` of the Docker image to perform the scan automatically, without passing any command. -The [`before_script`](../../ci/yaml/README.md#before_script) +The [`before_script`](../../ci/yaml/index.md#before_script) should not be used in the job definition because users may rely on this to prepare their projects before performing the scan. For instance, it is common practice to use `before_script` to install system libraries a particular project needs before performing SAST or Dependency Scanning. -Similarly, [`after_script`](../../ci/yaml/README.md#after_script) +Similarly, [`after_script`](../../ci/yaml/index.md#after_script) should not be used in the job definition, because it may be overridden by users. ### Stage For consistency, scanning jobs should belong to the `test` stage when possible. -The [`stage`](../../ci/yaml/README.md#stage) keyword can be omitted because `test` is the default value. +The [`stage`](../../ci/yaml/index.md#stage) keyword can be omitted because `test` is the default value. ### Fail-safe To be aligned with the [GitLab Security paradigm](https://about.gitlab.com/direction/secure/#security-paradigm), scanning jobs should not block the pipeline when they fail, -so the [`allow_failure`](../../ci/yaml/README.md#allow_failure) parameter should be set to `true`. +so the [`allow_failure`](../../ci/yaml/index.md#allow_failure) parameter should be set to `true`. ### Artifacts Scanning jobs must declare a report that corresponds to the type of scanning they perform, -using the [`artifacts:reports`](../../ci/yaml/README.md#artifactsreports) keyword. +using the [`artifacts:reports`](../../ci/yaml/index.md#artifactsreports) keyword. Valid reports are: `dependency_scanning`, `container_scanning`, `dast`, `api_fuzzing`, `coverage_fuzzing`, and `sast`. For example, here is the definition of a SAST job that generates a file named `gl-sast-report.json`, @@ -209,7 +209,7 @@ It is recommended to name the output file after the type of scanning, and to use Since all Secure reports are JSON files, it is recommended to use `.json` as a file extension. For instance, a suggested filename for a Dependency Scanning report is `gl-dependency-scanning.json`. -The [`artifacts:reports`](../../ci/yaml/README.md#artifactsreports) keyword +The [`artifacts:reports`](../../ci/yaml/index.md#artifactsreports) keyword of the job definition must be consistent with the file path where the Security report is written. For instance, if a Dependency Scanning analyzer writes its report to the CI project directory, and if this report filename is `depscan.json`, diff --git a/doc/development/integrations/secure_partner_integration.md b/doc/development/integrations/secure_partner_integration.md index e6048bed152..a143c654c21 100644 --- a/doc/development/integrations/secure_partner_integration.md +++ b/doc/development/integrations/secure_partner_integration.md @@ -83,7 +83,7 @@ and complete an integration with the Secure stage. 1. Ensure your pipeline jobs create a report artifact that GitLab can process to successfully display your own product's results with the rest of GitLab. - See detailed [technical directions](secure.md) for this step. - - Read more about [job report artifacts](../../ci/yaml/README.md#artifactsreports). + - Read more about [job report artifacts](../../ci/yaml/index.md#artifactsreports). - Read about [job artifacts](../../ci/pipelines/job_artifacts.md). - Your report artifact must be in one of our currently supported formats. For more information, see the [documentation on reports](secure.md#report). diff --git a/doc/development/pipelines.md b/doc/development/pipelines.md index 5dd586105e9..0ae71895acd 100644 --- a/doc/development/pipelines.md +++ b/doc/development/pipelines.md @@ -14,12 +14,12 @@ which itself includes files under for easier maintenance. We're striving to [dogfood](https://about.gitlab.com/handbook/engineering/#dogfooding) -GitLab [CI/CD features and best-practices](../ci/yaml/README.md) +GitLab [CI/CD features and best-practices](../ci/yaml/index.md) as much as possible. ## Overview -Pipelines for the GitLab project are created using the [`workflow:rules` keyword](../ci/yaml/README.md#workflow) +Pipelines for the GitLab project are created using the [`workflow:rules` keyword](../ci/yaml/index.md#workflow) feature of the GitLab CI/CD. Pipelines are always created for the following scenarios: @@ -49,7 +49,7 @@ depending on the changes made in the MR: - [Frontend-only MR pipeline](#frontend-only-mr-pipeline): This is typically created for an MR that only changes frontend code. - [QA-only MR pipeline](#qa-only-mr-pipeline): This is typically created for an MR that only changes end to end tests related code. -We use the [`rules:`](../ci/yaml/README.md#rules) and [`needs:`](../ci/yaml/README.md#needs) keywords extensively +We use the [`rules:`](../ci/yaml/index.md#rules) and [`needs:`](../ci/yaml/index.md#needs) keywords extensively to determine the jobs that need to be run in a pipeline. Note that an MR that includes multiple types of changes would have a pipelines that include jobs from multiple types (e.g. a combination of docs-only and code-only pipelines). @@ -537,7 +537,7 @@ the `gitlab-org/gitlab-foss` project. ### Interruptible pipelines -By default, all jobs are [interruptible](../ci/yaml/README.md#interruptible), except the +By default, all jobs are [interruptible](../ci/yaml/index.md#interruptible), except the `dont-interrupt-me` job which runs automatically on `main`, and is `manual` otherwise. @@ -717,13 +717,13 @@ each pipeline includes default variables defined in ### Common job definitions -Most of the jobs [extend from a few CI definitions](../ci/yaml/README.md#extends) +Most of the jobs [extend from a few CI definitions](../ci/yaml/index.md#extends) defined in [`.gitlab/ci/global.gitlab-ci.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/.gitlab/ci/global.gitlab-ci.yml) -that are scoped to a single [configuration keyword](../ci/yaml/README.md#job-keywords). +that are scoped to a single [configuration keyword](../ci/yaml/index.md#job-keywords). | Job definitions | Description | |------------------|-------------| -| `.default-retry` | Allows a job to [retry](../ci/yaml/README.md#retry) upon `unknown_failure`, `api_failure`, `runner_system_failure`, `job_execution_timeout`, or `stuck_or_timeout_failure`. | +| `.default-retry` | Allows a job to [retry](../ci/yaml/index.md#retry) upon `unknown_failure`, `api_failure`, `runner_system_failure`, `job_execution_timeout`, or `stuck_or_timeout_failure`. | | `.default-before_script` | Allows a job to use a default `before_script` definition suitable for Ruby/Rails tasks that may need a database running (e.g. tests). | | `.setup-test-env-cache` | Allows a job to use a default `cache` definition suitable for setting up test environment for subsequent Ruby/Rails tasks. | | `.rails-cache` | Allows a job to use a default `cache` definition suitable for Ruby/Rails tasks. | @@ -742,16 +742,16 @@ that are scoped to a single [configuration keyword](../ci/yaml/README.md#job-key ### `rules`, `if:` conditions and `changes:` patterns -We're using the [`rules` keyword](../ci/yaml/README.md#rules) extensively. +We're using the [`rules` keyword](../ci/yaml/index.md#rules) extensively. All `rules` definitions are defined in [`rules.gitlab-ci.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/.gitlab/ci/rules.gitlab-ci.yml), -then included in individual jobs via [`extends`](../ci/yaml/README.md#extends). +then included in individual jobs via [`extends`](../ci/yaml/index.md#extends). The `rules` definitions are composed of `if:` conditions and `changes:` patterns, which are also defined in [`rules.gitlab-ci.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/.gitlab/ci/rules.gitlab-ci.yml) -and included in `rules` definitions via [YAML anchors](../ci/yaml/README.md#anchors) +and included in `rules` definitions via [YAML anchors](../ci/yaml/index.md#anchors) #### `if:` conditions diff --git a/doc/index.md b/doc/index.md index cdb1114ca40..ed95b40130b 100644 --- a/doc/index.md +++ b/doc/index.md @@ -40,7 +40,7 @@ Have a look at some of our most popular topics: |:-------------------------------------------------------------------------------------------|:------------| | [Two-factor authentication](user/profile/account/two_factor_authentication.md) | Improve the security of your GitLab account. | | [GitLab groups](user/group/index.md) | Manage projects together. | -| [GitLab CI/CD pipeline configuration reference](ci/yaml/README.md) | Available configuration options for `.gitlab-ci.yml` files. | +| [GitLab CI/CD pipeline configuration reference](ci/yaml/index.md) | Available configuration options for `.gitlab-ci.yml` files. | | [Activate GitLab EE with a license](user/admin_area/license.md) | Activate GitLab Enterprise Edition functionality with a license. | | [Back up and restore GitLab](raketasks/backup_restore.md) | Rake tasks for backing up and restoring GitLab self-managed instances. | | [GitLab release and maintenance policy](policy/maintenance.md) | Policies for version naming and cadence, and also upgrade recommendations. | diff --git a/doc/install/aws/index.md b/doc/install/aws/index.md index df18c5255a4..5abc4bd3122 100644 --- a/doc/install/aws/index.md +++ b/doc/install/aws/index.md @@ -841,6 +841,6 @@ If you see this page when trying to set a password via the web interface, make s ### Some job logs are not uploaded to object storage -When the GitLab deployment is scaled up to more than one node, some job logs may not be uploaded to [object storage](../../administration/object_storage.md) properly. [Incremental logging is required](../../administration/object_storage.md#incremental-logging-is-required-for-ci-to-use-object-storage) for CI to use object storage. +When the GitLab deployment is scaled up to more than one node, some job logs may not be uploaded to [object storage](../../administration/object_storage.md) properly. [Incremental logging is required](../../administration/object_storage.md#other-alternatives-to-file-system-storage) for CI to use object storage. Enable [incremental logging](../../administration/job_logs.md#enable-or-disable-incremental-logging) if it has not already been enabled. diff --git a/doc/topics/autodevops/customize.md b/doc/topics/autodevops/customize.md index 73500973d90..011b8b7b949 100644 --- a/doc/topics/autodevops/customize.md +++ b/doc/topics/autodevops/customize.md @@ -187,11 +187,11 @@ to the desired environment. See [Limit environment scope of CI/CD variables](../ Auto DevOps is completely customizable because the [Auto DevOps template](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Auto-DevOps.gitlab-ci.yml) -is just an implementation of a [`.gitlab-ci.yml`](../../ci/yaml/README.md) file, +is just an implementation of a [`.gitlab-ci.yml`](../../ci/yaml/index.md) file, and uses only features available to any implementation of `.gitlab-ci.yml`. To modify the CI/CD pipeline used by Auto DevOps, -[`include` the template](../../ci/yaml/README.md#includetemplate), and customize +[`include` the template](../../ci/yaml/index.md#includetemplate), and customize it as needed by adding a `.gitlab-ci.yml` file to the root of your repository containing the following: @@ -202,7 +202,7 @@ include: Add your changes, and your additions are merged with the [Auto DevOps template](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Auto-DevOps.gitlab-ci.yml) -using the behavior described for [`include`](../../ci/yaml/README.md#include). +using the behavior described for [`include`](../../ci/yaml/index.md#include). If you need to specifically remove a part of the file, you can also copy and paste the contents of the [Auto DevOps template](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Auto-DevOps.gitlab-ci.yml) @@ -254,13 +254,13 @@ include: See the [Auto DevOps template](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Auto-DevOps.gitlab-ci.yml) for information on available jobs. WARNING: -Auto DevOps templates using the [`only`](../../ci/yaml/README.md#only--except) or -[`except`](../../ci/yaml/README.md#only--except) syntax have switched -to the [`rules`](../../ci/yaml/README.md#rules) syntax, starting in +Auto DevOps templates using the [`only`](../../ci/yaml/index.md#only--except) or +[`except`](../../ci/yaml/index.md#only--except) syntax have switched +to the [`rules`](../../ci/yaml/index.md#rules) syntax, starting in [GitLab 13.0](https://gitlab.com/gitlab-org/gitlab/-/issues/213336). If your `.gitlab-ci.yml` extends these Auto DevOps templates and override the `only` or `except` keywords, you must migrate your templates to use the -[`rules`](../../ci/yaml/README.md#rules) syntax after the +[`rules`](../../ci/yaml/index.md#rules) syntax after the base template is migrated to use the `rules` syntax. For users who cannot migrate just yet, you can alternatively pin your templates to the [GitLab 12.10 based templates](https://gitlab.com/gitlab-org/auto-devops-v12-10). diff --git a/doc/topics/autodevops/index.md b/doc/topics/autodevops/index.md index 1f49a7b21c5..ea1c716bd07 100644 --- a/doc/topics/autodevops/index.md +++ b/doc/topics/autodevops/index.md @@ -63,7 +63,7 @@ Since [GitLab 12.7](https://gitlab.com/gitlab-org/gitlab/-/issues/26655), Auto DevOps runs on pipelines automatically only if a [`Dockerfile` or matching buildpack](stages.md#auto-build) exists. -If a [CI/CD configuration file](../../ci/yaml/README.md) is present in the +If a [CI/CD configuration file](../../ci/yaml/index.md) is present in the project, it isn't changed and won't be affected by Auto DevOps. ### At the project level diff --git a/doc/topics/autodevops/requirements.md b/doc/topics/autodevops/requirements.md index 7e59ecb4916..1b3ca07f665 100644 --- a/doc/topics/autodevops/requirements.md +++ b/doc/topics/autodevops/requirements.md @@ -125,7 +125,7 @@ only the deployment to Kubernetes runs. WARNING: Setting the `AUTO_DEVOPS_PLATFORM_TARGET` variable to `ECS` triggers jobs defined in the [`Jobs/Deploy/ECS.gitlab-ci.yml` template](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Jobs/Deploy/ECS.gitlab-ci.yml). -However, it's not recommended to [include](../../ci/yaml/README.md#includetemplate) +However, it's not recommended to [include](../../ci/yaml/index.md#includetemplate) it on its own. This template is designed to be used with Auto DevOps only. It may change unexpectedly causing your pipeline to fail if included on its own. Also, the job names within this template may also change. Do not override these jobs' names in your diff --git a/doc/topics/autodevops/upgrading_auto_deploy_dependencies.md b/doc/topics/autodevops/upgrading_auto_deploy_dependencies.md index 15eb2b94738..4cf699ce25a 100644 --- a/doc/topics/autodevops/upgrading_auto_deploy_dependencies.md +++ b/doc/topics/autodevops/upgrading_auto_deploy_dependencies.md @@ -31,11 +31,11 @@ are using. First verify which template is in use: - [The GitLab.com stable Auto Deploy template](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Jobs/Deploy.gitlab-ci.yml) is being used if **one** of the following is true: - Your Auto DevOps project doesn't have a `.gitlab-ci.yml` file. - - Your Auto DevOps project has a `.gitlab-ci.yml` and [includes](../../ci/yaml/README.md#includetemplate) + - Your Auto DevOps project has a `.gitlab-ci.yml` and [includes](../../ci/yaml/index.md#includetemplate) the `Auto-DevOps.gitlab-ci.yml` template. - [The latest Auto Deploy template](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Jobs/Deploy.latest.gitlab-ci.yml) is being used if **both** of the following is true: - - Your Auto DevOps project has a `.gitlab-ci.yml` file and [includes](../../ci/yaml/README.md#includetemplate) + - Your Auto DevOps project has a `.gitlab-ci.yml` file and [includes](../../ci/yaml/index.md#includetemplate) the `Auto-DevOps.gitlab-ci.yml` template. - It also includes [the latest Auto Deploy template](#early-adopters) diff --git a/doc/user/admin_area/settings/continuous_integration.md b/doc/user/admin_area/settings/continuous_integration.md index 16899537bed..795144a64c1 100644 --- a/doc/user/admin_area/settings/continuous_integration.md +++ b/doc/user/admin_area/settings/continuous_integration.md @@ -88,7 +88,7 @@ The setting at all levels is only available to GitLab administrators. The default expiration time of the [job artifacts](../../../administration/job_artifacts.md) can be set in the Admin Area of your GitLab instance. The syntax of duration is -described in [`artifacts:expire_in`](../../../ci/yaml/README.md#artifactsexpire_in) +described in [`artifacts:expire_in`](../../../ci/yaml/index.md#artifactsexpire_in) and the default value is `30 days`. 1. On the top bar, select **Menu >** **{admin}** **Admin**. @@ -97,7 +97,7 @@ and the default value is `30 days`. 1. Click **Save changes** for the changes to take effect. This setting is set per job and can be overridden in -[`.gitlab-ci.yml`](../../../ci/yaml/README.md#artifactsexpire_in). +[`.gitlab-ci.yml`](../../../ci/yaml/index.md#artifactsexpire_in). To disable the expiration, set it to `0`. The default unit is in seconds. NOTE: @@ -233,13 +233,13 @@ use a template from: NOTE: When you use a configuration defined in an instance template repository, - nested [`include:`](../../../ci/yaml/README.md#include) keywords + nested [`include:`](../../../ci/yaml/index.md#include) keywords (including `include:file`, `include:local`, `include:remote`, and `include:template`) [do not work](https://gitlab.com/gitlab-org/gitlab/-/issues/35345). The project CI/CD configuration merges into the required pipeline configuration when a pipeline runs. The merged configuration is the same as if the required pipeline configuration -added the project configuration with the [`include` keyword](../../../ci/yaml/README.md#include). +added the project configuration with the [`include` keyword](../../../ci/yaml/index.md#include). To view a project's full merged configuration, [View the merged YAML](../../../ci/pipeline_editor/index.md#view-expanded-configuration) in the pipeline editor. diff --git a/doc/user/admin_area/settings/index.md b/doc/user/admin_area/settings/index.md index 6a5af09358d..937ec9fe062 100644 --- a/doc/user/admin_area/settings/index.md +++ b/doc/user/admin_area/settings/index.md @@ -68,7 +68,7 @@ To access the default page for Admin Area settings: | Option | Description | | ------ | ----------- | | [Continuous Integration and Deployment](continuous_integration.md) | Auto DevOps, runners and job artifacts. | -| [Required pipeline configuration](continuous_integration.md#required-pipeline-configuration) **(PREMIUM SELF)** | Set an instance-wide auto included [pipeline configuration](../../../ci/yaml/README.md). This pipeline configuration is run after the project's own configuration. | +| [Required pipeline configuration](continuous_integration.md#required-pipeline-configuration) **(PREMIUM SELF)** | Set an instance-wide auto included [pipeline configuration](../../../ci/yaml/index.md). This pipeline configuration is run after the project's own configuration. | | [Package Registry](continuous_integration.md#package-registry-configuration) | Settings related to the use and experience of using the GitLab Package Registry. Note there are [risks involved](../../packages/container_registry/index.md#use-with-external-container-registries) in enabling some of these settings. | ## Reporting diff --git a/doc/user/analytics/value_stream_analytics.md b/doc/user/analytics/value_stream_analytics.md index 98948243724..4ad3a03a5b0 100644 --- a/doc/user/analytics/value_stream_analytics.md +++ b/doc/user/analytics/value_stream_analytics.md @@ -112,7 +112,7 @@ environments is configured. 1. Push branch, and create a merge request that contains the [issue closing pattern](../project/issues/managing_issues.md#closing-issues-automatically) in its description at 14:00 (stop of **Code** stage and start of **Test** and **Review** stages). -1. The CI starts running your scripts defined in [`.gitlab-ci.yml`](../../ci/yaml/README.md) and +1. The CI starts running your scripts defined in [`.gitlab-ci.yml`](../../ci/yaml/index.md) and takes 5 minutes (stop of **Test** stage). 1. Review merge request, ensure that everything is okay, and then merge the merge request at 19:00 (stop of **Review** stage and start of **Staging** stage). diff --git a/doc/user/application_security/api_fuzzing/index.md b/doc/user/application_security/api_fuzzing/index.md index 4abec0f1c67..e35415003c7 100644 --- a/doc/user/application_security/api_fuzzing/index.md +++ b/doc/user/application_security/api_fuzzing/index.md @@ -134,7 +134,7 @@ To configure API fuzzing in GitLab with an OpenAPI Specification: 1. Add the `fuzz` stage to your `.gitlab-ci.yml` file. -1. [Include](../../../ci/yaml/README.md#includetemplate) +1. [Include](../../../ci/yaml/index.md#includetemplate) the [`API-Fuzzing.gitlab-ci.yml` template](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Security/API-Fuzzing.gitlab-ci.yml) in your `.gitlab-ci.yml` file. @@ -200,7 +200,7 @@ To configure API fuzzing to use a HAR file: 1. Add the `fuzz` stage to your `.gitlab-ci.yml` file. -1. [Include](../../../ci/yaml/README.md#includetemplate) +1. [Include](../../../ci/yaml/index.md#includetemplate) the [`API-Fuzzing.gitlab-ci.yml` template](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Security/API-Fuzzing.gitlab-ci.yml) in your `.gitlab-ci.yml` file. @@ -271,7 +271,7 @@ To configure API fuzzing to use a Postman Collection file: 1. Add the `fuzz` stage to your `.gitlab-ci.yml` file. -1. [Include](../../../ci/yaml/README.md#includetemplate) +1. [Include](../../../ci/yaml/index.md#includetemplate) the [`API-Fuzzing.gitlab-ci.yml` template](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Security/API-Fuzzing.gitlab-ci.yml) in your `.gitlab-ci.yml` file. diff --git a/doc/user/application_security/container_scanning/index.md b/doc/user/application_security/container_scanning/index.md index fbe4f1c3d04..fc2a76b808b 100644 --- a/doc/user/application_security/container_scanning/index.md +++ b/doc/user/application_security/container_scanning/index.md @@ -59,7 +59,7 @@ To enable container scanning in your pipeline, you need the following: How you enable container scanning depends on your GitLab version: -- GitLab 11.9 and later: [Include](../../../ci/yaml/README.md#includetemplate) the +- GitLab 11.9 and later: [Include](../../../ci/yaml/index.md#includetemplate) the [`Container-Scanning.gitlab-ci.yml` template](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Security/Container-Scanning.gitlab-ci.yml) that comes with your GitLab installation. - GitLab versions earlier than 11.9: Copy and use the job from the @@ -73,8 +73,8 @@ Other changes: [`centos:centos8`](https://hub.docker.com/_/centos) as the new base. It also removes the use of the [start.sh](https://gitlab.com/gitlab-org/security-products/analyzers/klar/-/merge_requests/77) script and instead executes the analyzer by default. Any customizations made to the - `container_scanning` job's [`before_script`](../../../ci/yaml/README.md#before_script) - and [`after_script`](../../../ci/yaml/README.md#after_script) + `container_scanning` job's [`before_script`](../../../ci/yaml/index.md#before_script) + and [`after_script`](../../../ci/yaml/index.md#after_script) blocks may not work with the new version. To roll back to the previous [`alpine:3.11.3`](https://hub.docker.com/_/alpine)-based Docker image, you can specify the major version through the [`CS_MAJOR_VERSION`](#available-cicd-variables) variable. @@ -101,7 +101,7 @@ The included template: (see [requirements](#requirements)) and scans it for possible vulnerabilities. GitLab saves the results as a -[Container Scanning report artifact](../../../ci/yaml/README.md#artifactsreportscontainer_scanning) +[Container Scanning report artifact](../../../ci/yaml/index.md#artifactsreportscontainer_scanning) that you can download and analyze later. When downloading, you always receive the most-recent artifact. @@ -130,12 +130,12 @@ include: There may be cases where you want to customize how GitLab scans your containers. For example, you may want to enable more verbose output, access a Docker registry that requires -authentication, and more. To change such settings, use the [`variables`](../../../ci/yaml/README.md#variables) +authentication, and more. To change such settings, use the [`variables`](../../../ci/yaml/index.md#variables) parameter in your `.gitlab-ci.yml` to set [CI/CD variables](#available-cicd-variables). The variables you set in your `.gitlab-ci.yml` overwrite those in `Container-Scanning.gitlab-ci.yml`. -This example [includes](../../../ci/yaml/README.md#include) the container scanning template and +This example [includes](../../../ci/yaml/index.md#include) the container scanning template and enables verbose output for the analyzer: ```yaml @@ -190,8 +190,8 @@ container_scanning: ``` WARNING: -GitLab 13.0 and later doesn't support [`only` and `except`](../../../ci/yaml/README.md#only--except). -When overriding the template, you must use [`rules`](../../../ci/yaml/README.md#rules) +GitLab 13.0 and later doesn't support [`only` and `except`](../../../ci/yaml/index.md#only--except). +When overriding the template, you must use [`rules`](../../../ci/yaml/index.md#rules) instead. ### Change scanners diff --git a/doc/user/application_security/coverage_fuzzing/index.md b/doc/user/application_security/coverage_fuzzing/index.md index ca74e011fb2..9555348dc66 100644 --- a/doc/user/application_security/coverage_fuzzing/index.md +++ b/doc/user/application_security/coverage_fuzzing/index.md @@ -38,7 +38,7 @@ Docker image with the fuzz engine to run your app. ## Configuration To enable fuzzing, you must -[include](../../../ci/yaml/README.md#includetemplate) +[include](../../../ci/yaml/index.md#includetemplate) the [`Coverage-Fuzzing.gitlab-ci.yml` template](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Security/Coverage-Fuzzing.gitlab-ci.yml) provided as part of your GitLab installation. @@ -59,8 +59,8 @@ my_fuzz_target: - ./gitlab-cov-fuzz run --regression=$REGRESSION -- ``` -The included template makes available the [hidden job](../../../ci/yaml/README.md#hide-jobs) -`.fuzz_base`, which you must [extend](../../../ci/yaml/README.md#extends) for each of your fuzz +The included template makes available the [hidden job](../../../ci/yaml/index.md#hide-jobs) +`.fuzz_base`, which you must [extend](../../../ci/yaml/index.md#extends) for each of your fuzz targets. Each fuzz target **must** have a separate job. For example, the [go-fuzzing-example project](https://gitlab.com/gitlab-org/security-products/demos/go-fuzzing-example) contains one job that extends `.fuzz_base` for its single fuzz target. diff --git a/doc/user/application_security/dast/index.md b/doc/user/application_security/dast/index.md index cf80b686db9..0168f37ea4d 100644 --- a/doc/user/application_security/dast/index.md +++ b/doc/user/application_security/dast/index.md @@ -202,7 +202,7 @@ To include the DAST template: 1. Add the template to GitLab, based on your version of GitLab: - - In GitLab 11.9 and later, [include](../../../ci/yaml/README.md#includetemplate) + - In GitLab 11.9 and later, [include](../../../ci/yaml/index.md#includetemplate) the template by adding the following to your `.gitlab-ci.yml` file: ```yaml @@ -218,7 +218,7 @@ To include the DAST template: 1. Define the URL to be scanned by DAST by using one of these methods: - - Set the `DAST_WEBSITE` [CI/CD variable](../../../ci/yaml/README.md#variables). + - Set the `DAST_WEBSITE` [CI/CD variable](../../../ci/yaml/index.md#variables). If set, this value takes precedence. - Add the URL in an `environment_url.txt` file at the root of your project. This is @@ -247,7 +247,7 @@ The included template creates a `dast` job in your CI/CD pipeline and scans your project's running application for possible vulnerabilities. The results are saved as a -[DAST report artifact](../../../ci/yaml/README.md#artifactsreportsdast) +[DAST report artifact](../../../ci/yaml/index.md#artifactsreportsdast) that you can later download and analyze. Due to implementation limitations, we always take the latest DAST artifact available. Behind the scenes, the [GitLab DAST Docker image](https://gitlab.com/gitlab-org/security-products/dast) @@ -487,11 +487,11 @@ To view details of vulnerabilities detected by DAST: ### Customizing the DAST settings WARNING: -Beginning in GitLab 13.0, the use of [`only` and `except`](../../../ci/yaml/README.md#only--except) -is no longer supported. When overriding the template, you must use [`rules`](../../../ci/yaml/README.md#rules) instead. +Beginning in GitLab 13.0, the use of [`only` and `except`](../../../ci/yaml/index.md#only--except) +is no longer supported. When overriding the template, you must use [`rules`](../../../ci/yaml/index.md#rules) instead. The DAST settings can be changed through CI/CD variables by using the -[`variables`](../../../ci/yaml/README.md#variables) parameter in `.gitlab-ci.yml`. +[`variables`](../../../ci/yaml/index.md#variables) parameter in `.gitlab-ci.yml`. These variables are documented in [available variables](#available-cicd-variables). For example: @@ -505,7 +505,7 @@ variables: DAST_SPIDER_MINS: 120 ``` -Because the template is [evaluated before](../../../ci/yaml/README.md#include) the pipeline +Because the template is [evaluated before](../../../ci/yaml/index.md#include) the pipeline configuration, the last mention of the variable takes precedence. #### Enabling and disabling rules @@ -958,6 +958,7 @@ Alternatively, you can use the CI/CD variable `SECURE_ANALYZERS_PREFIX` to overr > - The saved scans feature was [introduced](https://gitlab.com/groups/gitlab-org/-/epics/5100) in GitLab 13.9. > - The option to select a branch was [introduced](https://gitlab.com/groups/gitlab-org/-/epics/4847) in GitLab 13.10. > - DAST branch selection [feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/issues/322672) in GitLab 13.11. +> - Auditing for DAST profile management was [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/217872) in GitLab 14.1. An on-demand DAST scan runs outside the DevOps life cycle. Changes in your repository don't trigger the scan. You must start it manually. @@ -1281,6 +1282,13 @@ If a scanner profile is linked to a security policy, a user cannot delete the pr page. See [Scan Policies](../policies/index.md) for more information. +### Auditing + +> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/217872) in GitLab 14.1. + +The creation, updating, and deletion of DAST profiles, DAST scanner profiles, +and DAST site profiles are included in the [audit log](../../../administration/audit_events.md). + ## Reports The DAST tool outputs a report file in JSON format by default. However, this tool can also generate reports in diff --git a/doc/user/application_security/dast_api/index.md b/doc/user/application_security/dast_api/index.md index d9d74dd25bb..48a784e0d03 100644 --- a/doc/user/application_security/dast_api/index.md +++ b/doc/user/application_security/dast_api/index.md @@ -85,7 +85,7 @@ the body generation is limited to these body types: Follow these steps to configure DAST API in GitLab with an OpenAPI specification: -1. To use DAST API, you must [include](../../../ci/yaml/README.md#includetemplate) +1. To use DAST API, you must [include](../../../ci/yaml/index.md#includetemplate) the [`DAST-API.gitlab-ci.yml` template](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Security/DAST-API.gitlab-ci.yml) that's provided as part of your GitLab installation. Add the following to your `.gitlab-ci.yml` file: @@ -184,7 +184,7 @@ cookies. We recommend that you review the HAR file contents before adding them t Follow these steps to configure DAST API to use a HAR file that provides information about the target API to test: -1. To use DAST API, you must [include](../../../ci/yaml/README.md#includetemplate) +1. To use DAST API, you must [include](../../../ci/yaml/index.md#includetemplate) the [`DAST-API.gitlab-ci.yml` template](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Security/DAST-API.gitlab-ci.yml) that's provided as part of your GitLab installation. To do so, add the following to your `.gitlab-ci.yml` file: @@ -284,7 +284,7 @@ them to a repository. Follow these steps to configure DAST API to use a Postman Collection file that provides information about the target API to test: -1. To use DAST API, you must [include](../../../ci/yaml/README.md#includetemplate) +1. To use DAST API, you must [include](../../../ci/yaml/index.md#includetemplate) the [`DAST-API.gitlab-ci.yml` template](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Security/DAST-API.gitlab-ci.yml) that's provided as part of your GitLab installation. To do so, add the following to your `.gitlab-ci.yml` file: diff --git a/doc/user/application_security/dependency_scanning/index.md b/doc/user/application_security/dependency_scanning/index.md index b864b0d84fe..33d6104998c 100644 --- a/doc/user/application_security/dependency_scanning/index.md +++ b/doc/user/application_security/dependency_scanning/index.md @@ -55,7 +55,7 @@ is **not** `19.03.0`. See [troubleshooting information](#error-response-from-dae ## Supported languages and package managers -GitLab relies on [`rules`](../../../ci/yaml/README.md#rules) to start relevant analyzers depending on the languages detected in the repository. +GitLab relies on [`rules`](../../../ci/yaml/index.md#rules) to start relevant analyzers depending on the languages detected in the repository. The current detection logic limits the maximum search depth to two levels. For example, the `gemnasium-dependency_scanning` job is enabled if a repository contains either a `Gemfile` or `api/Gemfile` file, but not if the only supported dependency file is `api/client/Gemfile`. The following languages and dependency managers are supported: @@ -90,7 +90,7 @@ The [Security Scanner Integration](../../../development/integrations/secure.md) ## Configuration To enable dependency scanning for GitLab 11.9 and later, you must -[include](../../../ci/yaml/README.md#includetemplate) the +[include](../../../ci/yaml/index.md#includetemplate) the [`Dependency-Scanning.gitlab-ci.yml` template](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Security/Dependency-Scanning.gitlab-ci.yml) that is provided as a part of your GitLab installation. For GitLab versions earlier than 11.9, you can copy and use the job as defined @@ -106,14 +106,14 @@ include: The included template creates dependency scanning jobs in your CI/CD pipeline and scans your project's source code for possible vulnerabilities. The results are saved as a -[dependency scanning report artifact](../../../ci/yaml/README.md#artifactsreportsdependency_scanning) +[dependency scanning report artifact](../../../ci/yaml/index.md#artifactsreportsdependency_scanning) that you can later download and analyze. Due to implementation limitations, we always take the latest dependency scanning artifact available. ### Customizing the dependency scanning settings The dependency scanning settings can be changed through [CI/CD variables](#available-cicd-variables) by using the -[`variables`](../../../ci/yaml/README.md#variables) parameter in `.gitlab-ci.yml`. +[`variables`](../../../ci/yaml/index.md#variables) parameter in `.gitlab-ci.yml`. For example: ```yaml @@ -124,14 +124,14 @@ variables: SECURE_LOG_LEVEL: error ``` -Because template is [evaluated before](../../../ci/yaml/README.md#include) the pipeline +Because template is [evaluated before](../../../ci/yaml/index.md#include) the pipeline configuration, the last mention of the variable takes precedence. ### Overriding dependency scanning jobs WARNING: -Beginning in GitLab 13.0, the use of [`only` and `except`](../../../ci/yaml/README.md#only--except) -is no longer supported. When overriding the template, you must use [`rules`](../../../ci/yaml/README.md#rules) instead. +Beginning in GitLab 13.0, the use of [`only` and `except`](../../../ci/yaml/index.md#only--except) +is no longer supported. When overriding the template, you must use [`rules`](../../../ci/yaml/index.md#rules) instead. To override a job definition (for example, to change properties like `variables` or `dependencies`), declare a new job with the same name as the one to override. Place this new job after the template @@ -596,7 +596,7 @@ Generally, the approach is the following: 1. Define a dedicated converter job in your `.gitlab-ci.yml` file. Use a suitable Docker image, script, or both to facilitate the conversion. 1. Let that job upload the converted, supported file as an artifact. -1. Add [`dependencies: []`](../../../ci/yaml/README.md#dependencies) +1. Add [`dependencies: []`](../../../ci/yaml/index.md#dependencies) to your `dependency_scanning` job to make use of the converted definitions files. For example, the currently unsupported `poetry.lock` file can be @@ -643,7 +643,7 @@ For information on this, see the [general Application Security troubleshooting s ### Limitation when using rules:exists The [dependency scanning CI template](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Security/Dependency-Scanning.gitlab-ci.yml) -uses the [`rules:exists`](../../../ci/yaml/README.md#rulesexists) +uses the [`rules:exists`](../../../ci/yaml/index.md#rulesexists) syntax. This directive is limited to 10000 checks and always returns `true` after reaching this number. Because of this, and depending on the number of files in your repository, a dependency scanning job might be triggered even if the scanner doesn't support your project. diff --git a/doc/user/application_security/index.md b/doc/user/application_security/index.md index 67aeb8c9a3e..9984e61dee6 100644 --- a/doc/user/application_security/index.md +++ b/doc/user/application_security/index.md @@ -129,7 +129,7 @@ All jobs are permitted to fail by default. This means that if they fail it do no If you want to prevent vulnerabilities from being merged, you should do this by adding [Security Approvals in Merge Requests](#security-approvals-in-merge-requests) which prevents unknown, high or critical findings from being merged without an approval from a specific group of people that you choose. -We do not recommend changing the job [`allow_failure` setting](../../ci/yaml/README.md#allow_failure) as that fails the entire pipeline. +We do not recommend changing the job [`allow_failure` setting](../../ci/yaml/index.md#allow_failure) as that fails the entire pipeline. ### JSON Artifact @@ -357,7 +357,7 @@ You can do it quickly by following the hyperlink given to run a new pipeline. ### Getting error message `sast job: stage parameter should be [some stage name here]` -When [including](../../ci/yaml/README.md#includetemplate) a `.gitlab-ci.yml` template +When [including](../../ci/yaml/index.md#includetemplate) a `.gitlab-ci.yml` template like [`SAST.gitlab-ci.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Security/SAST.gitlab-ci.yml), the following error may occur, depending on your GitLab CI/CD configuration: @@ -410,7 +410,7 @@ This provides useful information to investigate further. ### Getting error message `sast job: config key may not be used with 'rules': only/except` -When [including](../../ci/yaml/README.md#includetemplate) a `.gitlab-ci.yml` template +When [including](../../ci/yaml/index.md#includetemplate) a `.gitlab-ci.yml` template like [`SAST.gitlab-ci.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Security/SAST.gitlab-ci.yml), the following error may occur, depending on your GitLab CI/CD configuration: @@ -421,7 +421,7 @@ Found errors in your .gitlab-ci.yml: ``` This error appears when the included job's `rules` configuration has been [overridden](sast/index.md#overriding-sast-jobs) -with [the deprecated `only` or `except` syntax.](../../ci/yaml/README.md#only--except) +with [the deprecated `only` or `except` syntax.](../../ci/yaml/index.md#only--except) To fix this issue, you must either: - [Transition your `only/except` syntax to `rules`](#transitioning-your-onlyexcept-syntax-to-rules). @@ -432,8 +432,8 @@ To fix this issue, you must either: #### Transitioning your `only/except` syntax to `rules` When overriding the template to control job execution, previous instances of -[`only` or `except`](../../ci/yaml/README.md#only--except) are no longer compatible -and must be transitioned to [the `rules` syntax](../../ci/yaml/README.md#rules). +[`only` or `except`](../../ci/yaml/index.md#only--except) are no longer compatible +and must be transitioned to [the `rules` syntax](../../ci/yaml/index.md#rules). If your override is aimed at limiting jobs to only run on `master`, the previous syntax would look similar to: @@ -489,11 +489,11 @@ spotbugs-sast: - if: $CI_COMMIT_TAG == null ``` -[Learn more on the usage of `rules`](../../ci/yaml/README.md#rules). +[Learn more on the usage of `rules`](../../ci/yaml/index.md#rules). #### Pin your templates to the deprecated versions -To ensure the latest support, we **strongly** recommend that you migrate to [`rules`](../../ci/yaml/README.md#rules). +To ensure the latest support, we **strongly** recommend that you migrate to [`rules`](../../ci/yaml/index.md#rules). If you're unable to immediately update your CI configuration, there are several workarounds that involve pinning to the previous template versions, for example: diff --git a/doc/user/application_security/offline_deployments/index.md b/doc/user/application_security/offline_deployments/index.md index 8610055928e..d87da15b4b0 100644 --- a/doc/user/application_security/offline_deployments/index.md +++ b/doc/user/application_security/offline_deployments/index.md @@ -108,7 +108,7 @@ example of such a transfer: ### Using the official GitLab template -GitLab provides a [vendored template](../../../ci/yaml/README.md#includetemplate) +GitLab provides a [vendored template](../../../ci/yaml/index.md#includetemplate) to ease this process. This template should be used in a new, empty project, with a `gitlab-ci.yml` file containing: diff --git a/doc/user/application_security/sast/index.md b/doc/user/application_security/sast/index.md index d8da7c69d04..4291443caa9 100644 --- a/doc/user/application_security/sast/index.md +++ b/doc/user/application_security/sast/index.md @@ -162,7 +162,7 @@ To configure SAST for a project you can: ### Configure SAST manually -For GitLab 11.9 and later, to enable SAST you must [include](../../../ci/yaml/README.md#includetemplate) +For GitLab 11.9 and later, to enable SAST you must [include](../../../ci/yaml/index.md#includetemplate) the [`SAST.gitlab-ci.yml` template](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Security/SAST.gitlab-ci.yml) provided as a part of your GitLab installation. For GitLab versions earlier than 11.9, you can copy and use the job as defined that template. @@ -178,7 +178,7 @@ The included template creates SAST jobs in your CI/CD pipeline and scans your project's source code for possible vulnerabilities. The results are saved as a -[SAST report artifact](../../../ci/yaml/README.md#artifactsreportssast) +[SAST report artifact](../../../ci/yaml/index.md#artifactsreportssast) that you can later download and analyze. Due to implementation limitations, we always take the latest SAST artifact available. @@ -206,7 +206,7 @@ page: The SAST settings can be changed through [CI/CD variables](#available-cicd-variables) by using the -[`variables`](../../../ci/yaml/README.md#variables) parameter in `.gitlab-ci.yml`. +[`variables`](../../../ci/yaml/index.md#variables) parameter in `.gitlab-ci.yml`. In the following example, we include the SAST template and at the same time we set the `SAST_GOSEC_LEVEL` variable to `2`: @@ -218,14 +218,14 @@ variables: SAST_GOSEC_LEVEL: 2 ``` -Because the template is [evaluated before](../../../ci/yaml/README.md#include) +Because the template is [evaluated before](../../../ci/yaml/index.md#include) the pipeline configuration, the last mention of the variable takes precedence. ### Overriding SAST jobs WARNING: -Beginning in GitLab 13.0, the use of [`only` and `except`](../../../ci/yaml/README.md#only--except) -is no longer supported. When overriding the template, you must use [`rules`](../../../ci/yaml/README.md#rules) instead. +Beginning in GitLab 13.0, the use of [`only` and `except`](../../../ci/yaml/index.md#only--except) +is no longer supported. When overriding the template, you must use [`rules`](../../../ci/yaml/index.md#rules) instead. To override a job definition, (for example, change properties like `variables` or `dependencies`), declare a job with the same name as the SAST job to override. Place this new job after the template @@ -556,7 +556,7 @@ The SAST tool emits a JSON report file. For more information, see the [schema for this report](https://gitlab.com/gitlab-org/security-products/security-report-schemas/-/blob/master/dist/sast-report-format.json). The JSON report file can be downloaded from the CI pipelines page, or the -pipelines tab on merge requests by [setting `artifacts: paths`](../../../ci/yaml/README.md#artifactspaths) to `gl-sast-report.json`. For more information see [Downloading artifacts](../../../ci/pipelines/job_artifacts.md). +pipelines tab on merge requests by [setting `artifacts: paths`](../../../ci/yaml/index.md#artifactspaths) to `gl-sast-report.json`. For more information see [Downloading artifacts](../../../ci/pipelines/job_artifacts.md). Here's an example SAST report: @@ -765,7 +765,7 @@ uses the `rules:exists` parameter. For performance reasons, a maximum number of against the given glob pattern. If the number of matches exceeds the maximum, the `rules:exists` parameter returns `true`. Depending on the number of files in your repository, a SAST job might be triggered even if the scanner doesn't support your project. For more details about this issue, see -the [`rules:exists` documentation](../../../ci/yaml/README.md#rulesexists). +the [`rules:exists` documentation](../../../ci/yaml/index.md#rulesexists). ### SpotBugs UTF-8 unmappable character errors @@ -791,7 +791,7 @@ For Maven builds, add the following to your `pom.xml` file: ### Flawfinder encoding error -This occurs when Flawfinder encounters an invalid UTF-8 character. To fix this, convert all source code in your project to UTF-8 character encoding. This can be done with [`cvt2utf`](https://github.com/x1angli/cvt2utf) or [`iconv`](https://www.gnu.org/software/libiconv/documentation/libiconv-1.13/iconv.1.html) either over the entire project or per job using the [`before_script`](../../../ci/yaml/README.md#before_script) feature. +This occurs when Flawfinder encounters an invalid UTF-8 character. To fix this, convert all source code in your project to UTF-8 character encoding. This can be done with [`cvt2utf`](https://github.com/x1angli/cvt2utf) or [`iconv`](https://www.gnu.org/software/libiconv/documentation/libiconv-1.13/iconv.1.html) either over the entire project or per job using the [`before_script`](../../../ci/yaml/index.md#before_script) feature. ### Semgrep slowness, unexpected results, or other errors diff --git a/doc/user/application_security/secret_detection/index.md b/doc/user/application_security/secret_detection/index.md index f4aa9dc2787..72ef5b85e27 100644 --- a/doc/user/application_security/secret_detection/index.md +++ b/doc/user/application_security/secret_detection/index.md @@ -133,7 +133,7 @@ The included template creates Secret Detection jobs in your CI/CD pipeline and s your project's source code for secrets. The results are saved as a -[Secret Detection report artifact](../../../ci/yaml/README.md#artifactsreportssecret_detection) +[Secret Detection report artifact](../../../ci/yaml/index.md#artifactsreportssecret_detection) that you can later download and analyze. Due to implementation limitations, we always take the latest Secret Detection artifact available. @@ -166,15 +166,15 @@ that you can review and merge to complete the configuration. The Secret Detection scan settings can be changed through [CI/CD variables](#available-cicd-variables) by using the -[`variables`](../../../ci/yaml/README.md#variables) parameter in `.gitlab-ci.yml`. +[`variables`](../../../ci/yaml/index.md#variables) parameter in `.gitlab-ci.yml`. To override a job definition, (for example, change properties like `variables` or `dependencies`), declare a job with the same name as the SAST job to override. Place this new job after the template inclusion and specify any additional keys under it. WARNING: -Beginning in GitLab 13.0, the use of [`only` and `except`](../../../ci/yaml/README.md#only--except) -is no longer supported. When overriding the template, you must use [`rules`](../../../ci/yaml/README.md#rules) instead. +Beginning in GitLab 13.0, the use of [`only` and `except`](../../../ci/yaml/index.md#only--except) +is no longer supported. When overriding the template, you must use [`rules`](../../../ci/yaml/index.md#rules) instead. #### GIT_DEPTH @@ -197,7 +197,7 @@ secret_detection: SECRET_DETECTION_HISTORIC_SCAN: "true" ``` -Because the template is [evaluated before](../../../ci/yaml/README.md#include) +Because the template is [evaluated before](../../../ci/yaml/index.md#include) the pipeline configuration, the last mention of the variable takes precedence. #### Available CI/CD variables diff --git a/doc/user/application_security/security_dashboard/index.md b/doc/user/application_security/security_dashboard/index.md index 9728b12d785..3c12321ee25 100644 --- a/doc/user/application_security/security_dashboard/index.md +++ b/doc/user/application_security/security_dashboard/index.md @@ -39,7 +39,7 @@ The security dashboard and vulnerability report displays information about vulne 1. At least one project inside a group must be configured with at least one of the [supported reports](#supported-reports). -1. The configured jobs must use the [new `reports` syntax](../../../ci/yaml/README.md#artifactsreports). +1. The configured jobs must use the [new `reports` syntax](../../../ci/yaml/index.md#artifactsreports). 1. [GitLab Runner](https://docs.gitlab.com/runner/) 11.5 or newer must be used. If you're using the shared runners on GitLab.com, this is already the case. diff --git a/doc/user/clusters/management_project.md b/doc/user/clusters/management_project.md index 6f62d89677a..204afa9fc89 100644 --- a/doc/user/clusters/management_project.md +++ b/doc/user/clusters/management_project.md @@ -58,7 +58,7 @@ To select a cluster management project to use: ### Configuring your pipeline After designating a project as the management project for the cluster, -write a [`.gitlab-ci.yml`](../../ci/yaml/README.md) in that project. For example: +write a [`.gitlab-ci.yml`](../../ci/yaml/index.md) in that project. For example: ```yaml configure cluster: @@ -87,7 +87,7 @@ to a management project: | Production | `production` | The following environments set in -[`.gitlab-ci.yml`](../../ci/yaml/README.md) deploy to the +[`.gitlab-ci.yml`](../../ci/yaml/index.md) deploy to the Development, Staging, and Production cluster respectively. ```yaml diff --git a/doc/user/compliance/license_compliance/index.md b/doc/user/compliance/license_compliance/index.md index 901452cab16..8f978dfd0c7 100644 --- a/doc/user/compliance/license_compliance/index.md +++ b/doc/user/compliance/license_compliance/index.md @@ -90,11 +90,11 @@ To run a License Compliance scanning job, you need GitLab Runner with the ## Configuration For GitLab 12.8 and later, to enable License Compliance, you must -[include](../../../ci/yaml/README.md#includetemplate) the +[include](../../../ci/yaml/index.md#includetemplate) the [`License-Scanning.gitlab-ci.yml` template](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Security/License-Scanning.gitlab-ci.yml) that's provided as a part of your GitLab installation. For older versions of GitLab from 11.9 to 12.7, you must -[include](../../../ci/yaml/README.md#includetemplate) the +[include](../../../ci/yaml/index.md#includetemplate) the [`License-Management.gitlab-ci.yml` template](https://gitlab.com/gitlab-org/gitlab/-/blob/d2cc841c55d65bc8134bfb3a467e66c36ac32b0a/lib/gitlab/ci/templates/Security/License-Management.gitlab-ci.yml). For GitLab versions earlier than 11.9, you can copy and use the job as defined that template. @@ -115,14 +115,14 @@ the `license_management` job, so you must migrate to the `license_scanning` job `License-Scanning.gitlab-ci.yml` template. The results are saved as a -[License Compliance report artifact](../../../ci/yaml/README.md#artifactsreportslicense_scanning) +[License Compliance report artifact](../../../ci/yaml/index.md#artifactsreportslicense_scanning) that you can later download and analyze. Due to implementation limitations, we always take the latest License Compliance artifact available. Behind the scenes, the [GitLab License Compliance Docker image](https://gitlab.com/gitlab-org/security-products/analyzers/license-finder) is used to detect the languages/frameworks and in turn analyzes the licenses. The License Compliance settings can be changed through [CI/CD variables](#available-cicd-variables) by using the -[`variables`](../../../ci/yaml/README.md#variables) parameter in `.gitlab-ci.yml`. +[`variables`](../../../ci/yaml/index.md#variables) parameter in `.gitlab-ci.yml`. ### When License Compliance runs @@ -180,8 +180,8 @@ directory of your project. ### Overriding the template WARNING: -Beginning in GitLab 13.0, the use of [`only` and `except`](../../../ci/yaml/README.md#only--except) -is no longer supported. When overriding the template, you must use [`rules`](../../../ci/yaml/README.md#rules) instead. +Beginning in GitLab 13.0, the use of [`only` and `except`](../../../ci/yaml/index.md#only--except) +is no longer supported. When overriding the template, you must use [`rules`](../../../ci/yaml/index.md#rules) instead. If you want to override the job definition (for example, change properties like `variables` or `dependencies`), you need to declare a `license_scanning` job @@ -441,7 +441,7 @@ documentation for a list of settings that you can apply. The `license_scanning` job runs in a [Debian 10](https://www.debian.org/releases/buster/) Docker image. The supplied image ships with some build tools such as [CMake](https://cmake.org/) and [GCC](https://gcc.gnu.org/). However, not all project types are supported by default. To install additional tools needed to -compile dependencies, use a [`before_script`](../../../ci/yaml/README.md#before_script) +compile dependencies, use a [`before_script`](../../../ci/yaml/index.md#before_script) to install the necessary build tools using the [`apt`](https://wiki.debian.org/PackageManagementTools) package manager. For a comprehensive list, consult [the Conan documentation](https://docs.conan.io/en/latest/introduction.html#all-platforms-all-build-systems-and-compilers). diff --git a/doc/user/gitlab_com/index.md b/doc/user/gitlab_com/index.md index cd3411a44c8..188c80d8992 100644 --- a/doc/user/gitlab_com/index.md +++ b/doc/user/gitlab_com/index.md @@ -111,7 +111,7 @@ the related documentation. | Setting | GitLab.com | Default | |-------------------------------------|------------|---------| | Artifacts maximum size (compressed) | 1 GB | 100 MB | -| Artifacts [expiry time](../../ci/yaml/README.md#artifactsexpire_in) | From June 22, 2020, deleted after 30 days unless otherwise specified (artifacts created before that date have no expiry). | deleted after 30 days unless otherwise specified | +| Artifacts [expiry time](../../ci/yaml/index.md#artifactsexpire_in) | From June 22, 2020, deleted after 30 days unless otherwise specified (artifacts created before that date have no expiry). | deleted after 30 days unless otherwise specified | | Scheduled Pipeline Cron | `*/5 * * * *` | `3-59/10 * * * *` | | [Max jobs in active pipelines](../../administration/instance_limits.md#number-of-jobs-in-active-pipelines) | `500` for Free tier, unlimited otherwise | Unlimited | | [Max CI/CD subscriptions to a project](../../administration/instance_limits.md#number-of-cicd-subscriptions-to-a-project) | `2` | Unlimited | diff --git a/doc/user/group/clusters/index.md b/doc/user/group/clusters/index.md index bb082fba5e7..0d885183a41 100644 --- a/doc/user/group/clusters/index.md +++ b/doc/user/group/clusters/index.md @@ -122,7 +122,7 @@ For example, if your project has the following Kubernetes clusters: | Test | `test` | Group | | Development| `*` | Group | -And the following environments are set in [`.gitlab-ci.yml`](../../../ci/yaml/README.md): +And the following environments are set in [`.gitlab-ci.yml`](../../../ci/yaml/index.md): ```yaml stages: diff --git a/doc/user/group/value_stream_analytics/index.md b/doc/user/group/value_stream_analytics/index.md index 542ea81c04d..618f5cb229a 100644 --- a/doc/user/group/value_stream_analytics/index.md +++ b/doc/user/group/value_stream_analytics/index.md @@ -133,7 +133,7 @@ Value Stream Analytics dashboard does not present any data for: ## How the production environment is identified Value Stream Analytics identifies production environments by looking for project -[environments](../../../ci/yaml/README.md#environment) with a name matching any of these patterns: +[environments](../../../ci/yaml/index.md#environment) with a name matching any of these patterns: - `prod` or `prod/*` - `production` or `production/*` @@ -162,7 +162,7 @@ environments is configured. 1. Push branch and create a merge request that contains the [issue closing pattern](../../project/issues/managing_issues.md#closing-issues-automatically) in its description at 14:00 (stop of **Code** stage / start of **Test** and **Review** stages). -1. The CI starts running your scripts defined in [`.gitlab-ci.yml`](../../../ci/yaml/README.md) and +1. The CI starts running your scripts defined in [`.gitlab-ci.yml`](../../../ci/yaml/index.md) and takes 5min (stop of **Test** stage). 1. Review merge request, ensure that everything is OK and merge the merge request at 19:00. (stop of **Review** stage / start of **Staging** stage). diff --git a/doc/user/infrastructure/mr_integration.md b/doc/user/infrastructure/mr_integration.md index 6f8b1d8d569..66e00bab6ce 100644 --- a/doc/user/infrastructure/mr_integration.md +++ b/doc/user/infrastructure/mr_integration.md @@ -10,7 +10,7 @@ Collaborating around Infrastructure as Code (IaC) changes requires both code cha ## Output Terraform Plan information into a merge request -Using the [GitLab Terraform Report artifact](../../ci/yaml/README.md#artifactsreportsterraform), +Using the [GitLab Terraform Report artifact](../../ci/yaml/index.md#artifactsreportsterraform), you can expose details from `terraform plan` runs directly into a merge request widget, enabling you to see statistics about the resources that Terraform creates, modifies, or destroys. @@ -57,7 +57,7 @@ To manually configure a GitLab Terraform Report artifact requires the following 1. Define a `script` that runs `terraform plan` and `terraform show`. These commands pipe the output and convert the relevant bits into a store variable `PLAN_JSON`. This JSON is used to create a - [GitLab Terraform Report artifact](../../ci/yaml/README.md#artifactsreportsterraform). + [GitLab Terraform Report artifact](../../ci/yaml/index.md#artifactsreportsterraform). The Terraform report obtains a Terraform `tfplan.json` file. The collected Terraform plan report is uploaded to GitLab as an artifact, and is shown in merge requests. diff --git a/doc/user/packages/container_registry/index.md b/doc/user/packages/container_registry/index.md index 9bb539b14a8..450714c2c74 100644 --- a/doc/user/packages/container_registry/index.md +++ b/doc/user/packages/container_registry/index.md @@ -135,7 +135,7 @@ To view these commands, go to your project's **Packages & Registries > Container ## Build and push by using GitLab CI/CD -Use [GitLab CI/CD](../../../ci/yaml/README.md) to build and push images to the +Use [GitLab CI/CD](../../../ci/yaml/index.md) to build and push images to the Container Registry. Use it to test, build, and deploy your project from the Docker image you created. @@ -309,7 +309,7 @@ in addition to the steps in the [Docker-in-Docker](../../../ci/docker/using_docker_build.md#use-the-docker-executor-with-the-docker-image-docker-in-docker) section: 1. Update the `image` and `service` to point to your registry. -1. Add a service [alias](../../../ci/yaml/README.md#servicesalias). +1. Add a service [alias](../../../ci/yaml/index.md#servicesalias). Below is an example of what your `.gitlab-ci.yml` should look like: @@ -339,7 +339,7 @@ in addition to the steps in the [Docker-in-Docker](../../../ci/docker/using_docker_build.md#use-the-docker-executor-with-the-docker-image-docker-in-docker) section: 1. Update the `image` and `service` to point to your registry. -1. Add a service [alias](../../../ci/yaml/README.md#servicesalias). +1. Add a service [alias](../../../ci/yaml/index.md#servicesalias). Below is an example of what your `.gitlab-ci.yml` should look like: diff --git a/doc/user/packages/dependency_proxy/index.md b/doc/user/packages/dependency_proxy/index.md index b999b92637a..8f7efc5f7ed 100644 --- a/doc/user/packages/dependency_proxy/index.md +++ b/doc/user/packages/dependency_proxy/index.md @@ -134,13 +134,13 @@ To store a Docker image in Dependency Proxy storage: 1. Use one of these commands. In these examples, the image is `alpine:latest`. 1. You can also pull images by digest to specify exactly which version of an image to pull. - - Pull an image by tag by adding the image to your [`.gitlab-ci.yml`](../../../ci/yaml/README.md#image) file: + - Pull an image by tag by adding the image to your [`.gitlab-ci.yml`](../../../ci/yaml/index.md#image) file: ```shell image: gitlab.example.com/groupname/dependency_proxy/containers/alpine:latest ``` - - Pull an image by digest by adding the image to your [`.gitlab-ci.yml`](../../../ci/yaml/README.md#image) file: + - Pull an image by digest by adding the image to your [`.gitlab-ci.yml`](../../../ci/yaml/index.md#image) file: ```shell image: ${CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX}/alpine@sha256:c9375e662992791e3f39e919b26f510e5254b42792519c180aad254e6b38f4dc diff --git a/doc/user/project/clusters/multiple_kubernetes_clusters.md b/doc/user/project/clusters/multiple_kubernetes_clusters.md index 25e63ff00a3..e2eae011b8c 100644 --- a/doc/user/project/clusters/multiple_kubernetes_clusters.md +++ b/doc/user/project/clusters/multiple_kubernetes_clusters.md @@ -35,7 +35,7 @@ For example, let's say the following Kubernetes clusters exist in a project: | Production | `production` | And the following environments are set in -[`.gitlab-ci.yml`](../../../ci/yaml/README.md): +[`.gitlab-ci.yml`](../../../ci/yaml/index.md): ```yaml stages: diff --git a/doc/user/project/clusters/serverless/aws.md b/doc/user/project/clusters/serverless/aws.md index b071d70c016..6eafb4530d3 100644 --- a/doc/user/project/clusters/serverless/aws.md +++ b/doc/user/project/clusters/serverless/aws.md @@ -381,7 +381,7 @@ control to AWS Lambda, API Gateway, CloudFormation, and IAM resources. ### Crafting the `.gitlab-ci.yml` file -In a [`.gitlab-ci.yml`](../../../../ci/yaml/README.md) file in the root of your project, +In a [`.gitlab-ci.yml`](../../../../ci/yaml/index.md) file in the root of your project, add the following and replace `` with the name of the S3 bucket where you want to store your package: diff --git a/doc/user/project/deploy_boards.md b/doc/user/project/deploy_boards.md index 5a774a3dc96..a09448d4755 100644 --- a/doc/user/project/deploy_boards.md +++ b/doc/user/project/deploy_boards.md @@ -59,7 +59,7 @@ specific environment, there are a lot of use cases. To name a few: - You want to promote what's running in staging, to production. You go to the environments list, verify that what's running in staging is what you think is - running, then click on the [manual action](../../ci/yaml/README.md#whenmanual) to deploy to production. + running, then click on the [manual action](../../ci/yaml/index.md#whenmanual) to deploy to production. - You trigger a deploy, and you have many containers to upgrade so you know this takes a while (you've also throttled your deploy to only take down X containers at a time). But you need to tell someone when it's deployed, so you diff --git a/doc/user/project/integrations/mattermost_slash_commands.md b/doc/user/project/integrations/mattermost_slash_commands.md index 834bf15c287..619ae52481b 100644 --- a/doc/user/project/integrations/mattermost_slash_commands.md +++ b/doc/user/project/integrations/mattermost_slash_commands.md @@ -141,7 +141,7 @@ The available slash commands for Mattermost are: | ------- | ----------- | ------- | | /<trigger> issue new <title> ⇧ Shift+↵ Enter <description> | Create a new issue in the project that `` is tied to. `` is optional. | `/gitlab issue new We need to change the homepage` | | /<trigger> issue show <issue-number> | Show the issue with ID `` from the project that `` is tied to. | `/gitlab issue show 42` | -| /<trigger> deploy <environment> to <environment> | Start the CI job that deploys from one environment to another, for example `staging` to `production`. CI/CD must be [properly configured](../../../ci/yaml/README.md). | `/gitlab deploy staging to production` | +| /<trigger> deploy <environment> to <environment> | Start the CI job that deploys from one environment to another, for example `staging` to `production`. CI/CD must be [properly configured](../../../ci/yaml/index.md). | `/gitlab deploy staging to production` | To see a list of available commands to interact with GitLab, type the trigger word followed by help. Example: `/gitlab help` diff --git a/doc/user/project/merge_requests/accessibility_testing.md b/doc/user/project/merge_requests/accessibility_testing.md index b3c4264ac2a..2bc6d5bb148 100644 --- a/doc/user/project/merge_requests/accessibility_testing.md +++ b/doc/user/project/merge_requests/accessibility_testing.md @@ -37,7 +37,7 @@ This example shows how to run [pa11y](https://pa11y.org/) on your code with GitLab CI/CD using the [GitLab Accessibility Docker image](https://gitlab.com/gitlab-org/ci-cd/accessibility). For GitLab 12.9 and later, to define the `a11y` job, you must -[include](../../../ci/yaml/README.md#includetemplate) the +[include](../../../ci/yaml/index.md#includetemplate) the [`Accessibility.gitlab-ci.yml` template](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Verify/Accessibility.gitlab-ci.yml) included with your GitLab installation, as shown below. diff --git a/doc/user/project/merge_requests/browser_performance_testing.md b/doc/user/project/merge_requests/browser_performance_testing.md index ac7511b61b5..eff3a5bd99e 100644 --- a/doc/user/project/merge_requests/browser_performance_testing.md +++ b/doc/user/project/merge_requests/browser_performance_testing.md @@ -40,7 +40,7 @@ Consider the following workflow: ## How browser performance testing works First, define a job in your `.gitlab-ci.yml` file that generates the -[Browser Performance report artifact](../../../ci/yaml/README.md#artifactsreportsbrowser_performance). +[Browser Performance report artifact](../../../ci/yaml/index.md#artifactsreportsbrowser_performance). GitLab then checks this report, compares key performance metrics for each page between the source and target branches, and shows the information in the merge request. @@ -89,7 +89,7 @@ The above example: GitLab 12.3 or earlier, you must [add the configuration manually](#gitlab-versions-132-and-earlier). The template uses the [GitLab plugin for sitespeed.io](https://gitlab.com/gitlab-org/gl-performance), -and it saves the full HTML sitespeed.io report as a [Browser Performance report artifact](../../../ci/yaml/README.md#artifactsreportsbrowser_performance) +and it saves the full HTML sitespeed.io report as a [Browser Performance report artifact](../../../ci/yaml/index.md#artifactsreportsbrowser_performance) that you can later download and analyze. This implementation always takes the latest Browser Performance artifact available. If [GitLab Pages](../pages/index.md) is enabled, you can view the report directly in your browser. diff --git a/doc/user/project/merge_requests/code_quality.md b/doc/user/project/merge_requests/code_quality.md index 18226a99600..756c90ff52c 100644 --- a/doc/user/project/merge_requests/code_quality.md +++ b/doc/user/project/merge_requests/code_quality.md @@ -111,7 +111,7 @@ include: The above example creates a `code_quality` job in your CI/CD pipeline which scans your source code for code quality issues. The report is saved as a -[Code Quality report artifact](../../../ci/yaml/README.md#artifactsreportscodequality) +[Code Quality report artifact](../../../ci/yaml/index.md#artifactsreportscodequality) that you can later download and analyze. It's also possible to override the URL to the Code Quality image by @@ -282,7 +282,7 @@ run on [pipelines for merge requests](../../../ci/merge_request_pipelines/index. If pipelines for merge requests is enabled, the `code_quality:rules` must be redefined. -The template has these [`rules`](../../../ci/yaml/README.md#rules) for the `code quality` job: +The template has these [`rules`](../../../ci/yaml/index.md#rules) for the `code quality` job: ```yaml code_quality: @@ -292,7 +292,7 @@ code_quality: - if: '$CI_COMMIT_TAG || $CI_COMMIT_BRANCH' ``` -If you are using merge request pipelines, your `rules` (or [`workflow: rules`](../../../ci/yaml/README.md#workflow)) +If you are using merge request pipelines, your `rules` (or [`workflow: rules`](../../../ci/yaml/index.md#workflow)) might look like this example: ```yaml @@ -334,7 +334,7 @@ do this: 1. Define a job in your `.gitlab-ci.yml` file that generates the [Code Quality report - artifact](../../../ci/yaml/README.md#artifactsreportscodequality). + artifact](../../../ci/yaml/index.md#artifactsreportscodequality). 1. Configure your tool to generate the Code Quality report artifact as a JSON file that implements a subset of the [Code Climate spec](https://github.com/codeclimate/platform/blob/master/spec/analyzers/SPEC.md#data-types). @@ -535,7 +535,7 @@ This can be due to multiple reasons: - Your pipeline is not set to run the code quality job on your target branch. If there is no report generated from the target branch, your MR branch reports have nothing to compare to. - If no [degradation or error is detected](https://docs.codeclimate.com/docs/maintainability#section-checks), nothing is displayed. -- The [`artifacts:expire_in`](../../../ci/yaml/README.md#artifactsexpire_in) CI/CD +- The [`artifacts:expire_in`](../../../ci/yaml/index.md#artifactsexpire_in) CI/CD setting can cause the Code Quality artifact(s) to expire faster than desired. - The widgets use the pipeline of the latest commit to the target branch. If commits are made to the default branch that do not run the code quality job, this may cause the merge request widget to have no base report for comparison. - If you use the [`REPORT_STDOUT` environment variable](https://gitlab.com/gitlab-org/ci-cd/codequality#environment-variables), no report file is generated and nothing displays in the merge request. diff --git a/doc/user/project/merge_requests/fail_fast_testing.md b/doc/user/project/merge_requests/fail_fast_testing.md index 632f6770027..a1adaa3fc99 100644 --- a/doc/user/project/merge_requests/fail_fast_testing.md +++ b/doc/user/project/merge_requests/fail_fast_testing.md @@ -19,7 +19,7 @@ that it believes to be relevant to the input files. `tff` is designed for Ruby on Rails projects, so the `Verify/FailFast` template is configured to run when changes to Ruby files are detected. By default, it runs in -the [`.pre` stage](../../../ci/yaml/README.md#pre-and-post) of a GitLab CI/CD pipeline, +the [`.pre` stage](../../../ci/yaml/index.md#pre-and-post) of a GitLab CI/CD pipeline, before all other stages. ## Example use case @@ -62,7 +62,7 @@ rspec-complete: - bundle exec rspec ``` -To run the most relevant specs first instead of the whole suite, [`include`](../../../ci/yaml/README.md#include) +To run the most relevant specs first instead of the whole suite, [`include`](../../../ci/yaml/index.md#include) the template by adding the following to your CI/CD configuration: ```yaml diff --git a/doc/user/project/merge_requests/index.md b/doc/user/project/merge_requests/index.md index ea1da11905f..f853bba7ad4 100644 --- a/doc/user/project/merge_requests/index.md +++ b/doc/user/project/merge_requests/index.md @@ -119,7 +119,7 @@ For a software developer working in a team: 1. Pushes a commit with their final review. 1. [Approves the merge request](approvals/index.md). 1. Sets it to [merge when pipeline succeeds](merge_when_pipeline_succeeds.md). -1. Your changes get deployed to production with [manual actions](../../../ci/yaml/README.md#whenmanual) for GitLab CI/CD. +1. Your changes get deployed to production with [manual actions](../../../ci/yaml/index.md#whenmanual) for GitLab CI/CD. 1. Your implementations were successfully shipped to your customer. For a web developer writing a webpage for your company's website: diff --git a/doc/user/project/merge_requests/load_performance_testing.md b/doc/user/project/merge_requests/load_performance_testing.md index 4575cbcbcc6..fb9137e93e4 100644 --- a/doc/user/project/merge_requests/load_performance_testing.md +++ b/doc/user/project/merge_requests/load_performance_testing.md @@ -28,7 +28,7 @@ GET calls to a popular API endpoint in your application to see how it performs. ## How Load Performance Testing works First, define a job in your `.gitlab-ci.yml` file that generates the -[Load Performance report artifact](../../../ci/yaml/README.md#artifactsreportsload_performance). +[Load Performance report artifact](../../../ci/yaml/index.md#artifactsreportsload_performance). GitLab checks this report, compares key load performance metrics between the source and target branches, and then shows the information in a merge request widget: @@ -140,7 +140,7 @@ For example, you can override the duration of the test with a CLI option: GitLab only displays the key performance metrics in the MR widget if k6's results are saved via [summary export](https://k6.io/docs/results-visualization/json#summary-export) -as a [Load Performance report artifact](../../../ci/yaml/README.md#artifactsreportsload_performance). +as a [Load Performance report artifact](../../../ci/yaml/index.md#artifactsreportsload_performance). The latest Load Performance artifact available is always used, using the summary values from the test. diff --git a/doc/user/project/merge_requests/merge_when_pipeline_succeeds.md b/doc/user/project/merge_requests/merge_when_pipeline_succeeds.md index 6c1e33a9ace..d7e8f915246 100644 --- a/doc/user/project/merge_requests/merge_when_pipeline_succeeds.md +++ b/doc/user/project/merge_requests/merge_when_pipeline_succeeds.md @@ -67,8 +67,8 @@ You should be careful to configure CI/CD so that pipelines run for every merge r ### Limitations When this setting is enabled, a merge request is prevented from being merged if there -is no pipeline. This may conflict with some use cases where [`only/except`](../../../ci/yaml/README.md#only--except) -or [`rules`](../../../ci/yaml/README.md#rules) are used and they don't generate any pipelines. +is no pipeline. This may conflict with some use cases where [`only/except`](../../../ci/yaml/index.md#only--except) +or [`rules`](../../../ci/yaml/index.md#rules) are used and they don't generate any pipelines. You should ensure that [there is always a pipeline](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/54226) and that it's successful. @@ -101,7 +101,7 @@ for details on avoiding two pipelines for a single merge request. > [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/211482) in GitLab 13.1. -When the **Pipelines must succeed** checkbox is checked, [skipped pipelines](../../../ci/yaml/README.md#skip-pipeline) prevent +When the **Pipelines must succeed** checkbox is checked, [skipped pipelines](../../../ci/yaml/index.md#skip-pipeline) prevent merge requests from being merged. To change this behavior: 1. Navigate to your project's **Settings > General** page. diff --git a/doc/user/project/merge_requests/test_coverage_visualization.md b/doc/user/project/merge_requests/test_coverage_visualization.md index 7bb8c833be3..ce8bfa2d054 100644 --- a/doc/user/project/merge_requests/test_coverage_visualization.md +++ b/doc/user/project/merge_requests/test_coverage_visualization.md @@ -21,14 +21,14 @@ MR is merged. ## How test coverage visualization works Collecting the coverage information is done via GitLab CI/CD's -[artifacts reports feature](../../../ci/yaml/README.md#artifactsreports). +[artifacts reports feature](../../../ci/yaml/index.md#artifactsreports). You can specify one or more coverage reports to collect, including wildcard paths. GitLab then takes the coverage information in all the files and combines it together. For the coverage analysis to work, you have to provide a properly formatted [Cobertura XML](https://cobertura.github.io/cobertura/) report to -[`artifacts:reports:cobertura`](../../../ci/yaml/README.md#artifactsreportscobertura). +[`artifacts:reports:cobertura`](../../../ci/yaml/index.md#artifactsreportscobertura). This format was originally developed for Java, but most coverage analysis frameworks for other languages have plugins to add support for it, like: @@ -129,7 +129,7 @@ The `source` is ignored if the path does not follow this pattern. The parser ass ### JavaScript example -The following [`gitlab-ci.yml`](../../../ci/yaml/README.md) example uses [Mocha](https://mochajs.org/) +The following [`gitlab-ci.yml`](../../../ci/yaml/index.md) example uses [Mocha](https://mochajs.org/) JavaScript testing and [nyc](https://github.com/istanbuljs/nyc) coverage-tooling to generate the coverage artifact: @@ -147,7 +147,7 @@ test: #### Maven example -The following [`gitlab-ci.yml`](../../../ci/yaml/README.md) example for Java or Kotlin uses [Maven](https://maven.apache.org/) +The following [`gitlab-ci.yml`](../../../ci/yaml/index.md) example for Java or Kotlin uses [Maven](https://maven.apache.org/) to build the project and [JaCoCo](https://www.eclemma.org/jacoco/) coverage-tooling to generate the coverage artifact. You can check the [Docker image configuration and scripts](https://gitlab.com/haynes/jacoco2cobertura) if you want to build your own image. @@ -185,7 +185,7 @@ coverage-jdk11: #### Gradle example -The following [`gitlab-ci.yml`](../../../ci/yaml/README.md) example for Java or Kotlin uses [Gradle](https://gradle.org/) +The following [`gitlab-ci.yml`](../../../ci/yaml/index.md) example for Java or Kotlin uses [Gradle](https://gradle.org/) to build the project and [JaCoCo](https://www.eclemma.org/jacoco/) coverage-tooling to generate the coverage artifact. You can check the [Docker image configuration and scripts](https://gitlab.com/haynes/jacoco2cobertura) if you want to build your own image. @@ -223,7 +223,7 @@ coverage-jdk11: ### Python example -The following [`gitlab-ci.yml`](../../../ci/yaml/README.md) example for Python uses [pytest-cov](https://pytest-cov.readthedocs.io/) to collect test coverage data and [coverage.py](https://coverage.readthedocs.io/) to convert the report to use full relative paths. +The following [`gitlab-ci.yml`](../../../ci/yaml/index.md) example for Python uses [pytest-cov](https://pytest-cov.readthedocs.io/) to collect test coverage data and [coverage.py](https://coverage.readthedocs.io/) to convert the report to use full relative paths. The information isn't displayed without the conversion. This example assumes that the code for your package is in `src/` and your tests are in `tests.py`: @@ -243,7 +243,7 @@ run tests: ### C/C++ example -The following [`gitlab-ci.yml`](../../../ci/yaml/README.md) example for C/C++ with +The following [`gitlab-ci.yml`](../../../ci/yaml/index.md) example for C/C++ with `gcc` or `g++` as the compiler uses [`gcovr`](https://gcovr.com/en/stable/) to generate the coverage output file in Cobertura XML format. diff --git a/doc/user/project/merge_requests/testing_and_reports_in_merge_requests.md b/doc/user/project/merge_requests/testing_and_reports_in_merge_requests.md index c19cae3d7ff..134c6530d17 100644 --- a/doc/user/project/merge_requests/testing_and_reports_in_merge_requests.md +++ b/doc/user/project/merge_requests/testing_and_reports_in_merge_requests.md @@ -17,7 +17,7 @@ or link to useful information directly from merge requests: | [Browser Performance Testing](browser_performance_testing.md) **(PREMIUM)** | Quickly determine the browser performance impact of pending code changes. | | [Load Performance Testing](load_performance_testing.md) **(PREMIUM)** | Quickly determine the server performance impact of pending code changes. | | [Code Quality](code_quality.md) | Analyze your source code quality using the [Code Climate](https://codeclimate.com/) analyzer and show the Code Climate report right in the merge request widget area. | -| [Display arbitrary job artifacts](../../../ci/yaml/README.md#artifactsexpose_as) | Configure CI pipelines with the `artifacts:expose_as` parameter to directly link to selected [artifacts](../../../ci/pipelines/job_artifacts.md) in merge requests. | +| [Display arbitrary job artifacts](../../../ci/yaml/index.md#artifactsexpose_as) | Configure CI pipelines with the `artifacts:expose_as` parameter to directly link to selected [artifacts](../../../ci/pipelines/job_artifacts.md) in merge requests. | | [GitLab CI/CD](../../../ci/index.md) | Build, test, and deploy your code in a per-branch basis with built-in CI/CD. | | [Unit test reports](../../../ci/unit_test_reports.md) | Configure your CI jobs to use Unit test reports, and let GitLab display a report on the merge request so that it's easier and faster to identify the failure without having to check the entire job log. | | [License Compliance](../../compliance/license_compliance/index.md) **(ULTIMATE)** | Manage the licenses of your dependencies. | diff --git a/doc/user/project/pages/getting_started/pages_from_scratch.md b/doc/user/project/pages/getting_started/pages_from_scratch.md index 9f80e2e7613..c28233901c8 100644 --- a/doc/user/project/pages/getting_started/pages_from_scratch.md +++ b/doc/user/project/pages/getting_started/pages_from_scratch.md @@ -158,7 +158,7 @@ When it succeeds, go to **Settings > Pages** to view the URL where your site is now available. If you want to do more advanced tasks, you can update your `.gitlab-ci.yml` file -with [any of the available settings](../../../../ci/yaml/README.md). You can validate +with [any of the available settings](../../../../ci/yaml/index.md). You can validate your `.gitlab-ci.yml` file with the [CI Lint](../../../../ci/lint.md) tool that's included with GitLab. After successful execution of this `pages` job, a special `pages:deploy` job appears in the diff --git a/doc/user/project/pages/introduction.md b/doc/user/project/pages/introduction.md index 4d6a8653657..94656c91e98 100644 --- a/doc/user/project/pages/introduction.md +++ b/doc/user/project/pages/introduction.md @@ -22,7 +22,7 @@ In brief, this is what you need to upload your website in GitLab Pages: 1. Domain of the instance: domain name that is used for GitLab Pages (ask your administrator). -1. GitLab CI/CD: a `.gitlab-ci.yml` file with a specific job named [`pages`](../../../ci/yaml/README.md#pages) in the root directory of your repository. +1. GitLab CI/CD: a `.gitlab-ci.yml` file with a specific job named [`pages`](../../../ci/yaml/index.md#pages) in the root directory of your repository. 1. A directory called `public` in your site's repository containing the content to be published. 1. GitLab Runner enabled for the project. @@ -129,7 +129,7 @@ See this document for a [step-by-step guide](getting_started/pages_from_scratch. Remember that GitLab Pages are by default branch/tag agnostic and their deployment relies solely on what you specify in `.gitlab-ci.yml`. You can limit -the `pages` job with the [`only` parameter](../../../ci/yaml/README.md#only--except), +the `pages` job with the [`only` parameter](../../../ci/yaml/index.md#only--except), whenever a new commit is pushed to a branch used specifically for your pages. diff --git a/doc/user/project/releases/index.md b/doc/user/project/releases/index.md index 71cbff9e545..f5fbe515f0f 100644 --- a/doc/user/project/releases/index.md +++ b/doc/user/project/releases/index.md @@ -79,7 +79,7 @@ To create a new release through the GitLab UI: > [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/19298) in GitLab 12.7. -You can [create a release directly from the GitLab CI pipeline](../../../ci/yaml/README.md#release) +You can [create a release directly from the GitLab CI pipeline](../../../ci/yaml/index.md#release) by using a `release` node in the job definition. The release is created only if the job processes without error. If the Rails API returns an error @@ -428,14 +428,14 @@ Evidence collection snapshots are visible on the Releases page, along with the t > [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/32773) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 13.2. -When you create a release, if [job artifacts](../../../ci/yaml/README.md#artifactsreports) are included in the last pipeline that ran, they are automatically included in the release as release evidence. +When you create a release, if [job artifacts](../../../ci/yaml/index.md#artifactsreports) are included in the last pipeline that ran, they are automatically included in the release as release evidence. Although job artifacts normally expire, artifacts included in release evidence do not expire. To enable job artifact collection you need to specify both: -1. [`artifacts:paths`](../../../ci/yaml/README.md#artifactspaths) -1. [`artifacts:reports`](../../../ci/yaml/README.md#artifactsreports) +1. [`artifacts:paths`](../../../ci/yaml/index.md#artifactspaths) +1. [`artifacts:reports`](../../../ci/yaml/index.md#artifactsreports) ```yaml ruby: @@ -455,7 +455,7 @@ release evidence. If you [schedule release evidence collection](#schedule-release-evidence-collection), some artifacts may already be expired by the time of evidence collection. To avoid this you can use -the [`artifacts:expire_in`](../../../ci/yaml/README.md#artifactsexpire_in) +the [`artifacts:expire_in`](../../../ci/yaml/index.md#artifactsexpire_in) keyword. Learn more in [this issue](https://gitlab.com/gitlab-org/gitlab/-/issues/222351). ### Schedule release evidence collection diff --git a/doc/user/project/repository/index.md b/doc/user/project/repository/index.md index 2dab8060212..afdcf2a94fa 100644 --- a/doc/user/project/repository/index.md +++ b/doc/user/project/repository/index.md @@ -41,7 +41,7 @@ to a branch in the repository. When you use the command line, you can commit mul If the project is configured with [GitLab CI/CD](../../../ci/index.md), you trigger a pipeline per push, not per commit. - **Skip pipelines:** - Add the [`ci skip`](../../../ci/yaml/README.md#skip-pipeline) keyword to + Add the [`ci skip`](../../../ci/yaml/index.md#skip-pipeline) keyword to your commit message to make GitLab CI/CD skip the pipeline. - **Cross-link issues and merge requests:** Use [cross-linking](../issues/crosslinking_issues.md#from-commit-messages) diff --git a/doc/user/project/requirements/index.md b/doc/user/project/requirements/index.md index d7fbff23e5e..4ac1113152c 100644 --- a/doc/user/project/requirements/index.md +++ b/doc/user/project/requirements/index.md @@ -122,7 +122,7 @@ You can also sort the requirements list by: > - [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/2859) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 13.1. > - [Added](https://gitlab.com/gitlab-org/gitlab/-/issues/215514) ability to specify individual requirements and their statuses in [GitLab Ultimate](https://about.gitlab.com/pricing/) 13.2. -GitLab supports [requirements test reports](../../../ci/yaml/README.md#artifactsreportsrequirements) now. +GitLab supports [requirements test reports](../../../ci/yaml/index.md#artifactsreportsrequirements) now. You can add a job to your CI pipeline that, when triggered, marks all existing requirements as Satisfied (you may manually satisfy a requirement in the edit form [edit a requirement](#edit-a-requirement)). diff --git a/doc/user/project/settings/index.md b/doc/user/project/settings/index.md index 93260bd76c0..66c32405c99 100644 --- a/doc/user/project/settings/index.md +++ b/doc/user/project/settings/index.md @@ -165,7 +165,7 @@ cannot change them: - Includes any jobs that drive the logic of your job. - Explicitly set the container image file to run the job in. This ensures that your script steps execute in the correct environment. -- Explicitly set any relevant GitLab pre-defined [job keywords](../../../ci/yaml/README.md#job-keywords). +- Explicitly set any relevant GitLab pre-defined [job keywords](../../../ci/yaml/index.md#job-keywords). This ensures that your job uses the settings you intend and that they are not overriden by project-level pipelines. diff --git a/doc/user/project/web_ide/index.md b/doc/user/project/web_ide/index.md index 0e597725611..722505304c0 100644 --- a/doc/user/project/web_ide/index.md +++ b/doc/user/project/web_ide/index.md @@ -331,7 +331,7 @@ The [File Sync](#file-syncing-to-web-terminal) feature is supported on Kubernete In order to enable the Web IDE terminals you need to create the file `.gitlab/.gitlab-webide.yml` inside the repository's root. This -file is fairly similar to the [CI configuration file](../../../ci/yaml/README.md) +file is fairly similar to the [CI configuration file](../../../ci/yaml/index.md) syntax but with some restrictions: - No global blocks (such as `before_script` or `after_script`) can be defined. diff --git a/lib/banzai/reference_extractor.rb b/lib/banzai/reference_extractor.rb index 3fc3ae02088..af0dcad107e 100644 --- a/lib/banzai/reference_extractor.rb +++ b/lib/banzai/reference_extractor.rb @@ -11,11 +11,11 @@ module Banzai @texts_and_contexts << { text: text, context: context } end - def references(type, project, current_user = nil) + def references(type, project, current_user, ids_only: false) context = RenderContext.new(project, current_user) processor = Banzai::ReferenceParser[type].new(context) - processor.process(html_documents) + processor.process(html_documents, ids_only: ids_only) end def reset_memoized_values diff --git a/lib/banzai/reference_parser/base_parser.rb b/lib/banzai/reference_parser/base_parser.rb index 3dfea8ee895..0c015ba00c7 100644 --- a/lib/banzai/reference_parser/base_parser.rb +++ b/lib/banzai/reference_parser/base_parser.rb @@ -76,9 +76,11 @@ module Banzai end # Returns an Array of objects referenced by any of the given HTML nodes. - def referenced_by(nodes) + def referenced_by(nodes, options = {}) ids = unique_attribute_values(nodes, self.class.data_attribute) + return ids if options.fetch(:ids_only, false) + if ids.empty? references_relation.none else @@ -194,7 +196,7 @@ module Banzai # Processes the list of HTML documents and returns an Array containing all # the references. - def process(documents) + def process(documents, ids_only: false) type = self.class.reference_type reference_options = self.class.reference_options @@ -202,17 +204,17 @@ module Banzai Querying.css(document, "a[data-reference-type='#{type}'].gfm", reference_options).to_a end - gather_references(nodes) + gather_references(nodes, ids_only: ids_only) end # Gathers the references for the given HTML nodes. Returns visible # references and a list of nodes which are not visible to the user - def gather_references(nodes) + def gather_references(nodes, ids_only: false) nodes = nodes_user_can_reference(current_user, nodes) visible = nodes_visible_to_user(current_user, nodes) not_visible = nodes - visible - { visible: referenced_by(visible), not_visible: not_visible } + { visible: referenced_by(visible, ids_only: ids_only), not_visible: not_visible } end # Returns a Hash containing the projects for a given list of HTML nodes. diff --git a/lib/banzai/reference_parser/commit_parser.rb b/lib/banzai/reference_parser/commit_parser.rb index 0bfb6a92020..88896970bc6 100644 --- a/lib/banzai/reference_parser/commit_parser.rb +++ b/lib/banzai/reference_parser/commit_parser.rb @@ -5,7 +5,7 @@ module Banzai class CommitParser < BaseParser self.reference_type = :commit - def referenced_by(nodes) + def referenced_by(nodes, options = {}) commit_ids = commit_ids_per_project(nodes) projects = find_projects_for_hash_keys(commit_ids) diff --git a/lib/banzai/reference_parser/commit_range_parser.rb b/lib/banzai/reference_parser/commit_range_parser.rb index 480eefd5c4d..fb4a392105f 100644 --- a/lib/banzai/reference_parser/commit_range_parser.rb +++ b/lib/banzai/reference_parser/commit_range_parser.rb @@ -5,7 +5,7 @@ module Banzai class CommitRangeParser < BaseParser self.reference_type = :commit_range - def referenced_by(nodes) + def referenced_by(nodes, options = {}) range_ids = commit_range_ids_per_project(nodes) projects = find_projects_for_hash_keys(range_ids) diff --git a/lib/banzai/reference_parser/external_issue_parser.rb b/lib/banzai/reference_parser/external_issue_parser.rb index 029b09dcd25..e8ee337064a 100644 --- a/lib/banzai/reference_parser/external_issue_parser.rb +++ b/lib/banzai/reference_parser/external_issue_parser.rb @@ -5,7 +5,7 @@ module Banzai class ExternalIssueParser < BaseParser self.reference_type = :external_issue - def referenced_by(nodes) + def referenced_by(nodes, options = {}) issue_ids = issue_ids_per_project(nodes) projects = find_projects_for_hash_keys(issue_ids) issues = [] diff --git a/lib/banzai/reference_parser/issuable_parser.rb b/lib/banzai/reference_parser/issuable_parser.rb index f8c26288017..efcaa6664b6 100644 --- a/lib/banzai/reference_parser/issuable_parser.rb +++ b/lib/banzai/reference_parser/issuable_parser.rb @@ -13,7 +13,7 @@ module Banzai end end - def referenced_by(nodes) + def referenced_by(nodes, options = {}) records = records_for_nodes(nodes) nodes.map { |node| records[node] }.compact.uniq diff --git a/lib/banzai/reference_parser/user_parser.rb b/lib/banzai/reference_parser/user_parser.rb index 36c41c6615f..c40ca9dc7cd 100644 --- a/lib/banzai/reference_parser/user_parser.rb +++ b/lib/banzai/reference_parser/user_parser.rb @@ -5,7 +5,7 @@ module Banzai class UserParser < BaseParser self.reference_type = :user - def referenced_by(nodes) + def referenced_by(nodes, options = {}) group_ids = [] user_ids = [] project_ids = [] diff --git a/lib/gitlab/database.rb b/lib/gitlab/database.rb index be2ee9380bf..3c86a6ec0b8 100644 --- a/lib/gitlab/database.rb +++ b/lib/gitlab/database.rb @@ -2,6 +2,8 @@ module Gitlab module Database + CI_DATABASE_NAME = 'ci' + # This constant is used when renaming tables concurrently. # If you plan to rename a table using the `rename_table_safely` method, add your table here one milestone before the rename. # Example: @@ -68,6 +70,14 @@ module Gitlab end end + def self.has_config?(database_name) + Gitlab::Application.config.database_configuration[Rails.env].include?(database_name.to_s) + end + + def self.ci_database?(name) + name == CI_DATABASE_NAME + end + def self.username config['username'] || ENV['USER'] end diff --git a/lib/gitlab/database/postgresql_adapter/dump_schema_versions_mixin.rb b/lib/gitlab/database/postgresql_adapter/dump_schema_versions_mixin.rb index 59bd24d3c37..4cb7b516612 100644 --- a/lib/gitlab/database/postgresql_adapter/dump_schema_versions_mixin.rb +++ b/lib/gitlab/database/postgresql_adapter/dump_schema_versions_mixin.rb @@ -7,6 +7,8 @@ module Gitlab extend ActiveSupport::Concern def dump_schema_information # :nodoc: + return super unless ActiveRecord::Base.configurations.primary?(pool.db_config.name) + versions = schema_migration.all_versions Gitlab::Database::SchemaVersionFiles.touch_all(versions) if versions.any? diff --git a/lib/gitlab/database/postgresql_database_tasks/load_schema_versions_mixin.rb b/lib/gitlab/database/postgresql_database_tasks/load_schema_versions_mixin.rb index cf8342941c4..6914b7ea4fc 100644 --- a/lib/gitlab/database/postgresql_database_tasks/load_schema_versions_mixin.rb +++ b/lib/gitlab/database/postgresql_database_tasks/load_schema_versions_mixin.rb @@ -6,9 +6,14 @@ module Gitlab module LoadSchemaVersionsMixin extend ActiveSupport::Concern - def structure_load(*args) - super(*args) - Gitlab::Database::SchemaVersionFiles.load_all + def structure_load(...) + result = super(...) + + if ActiveRecord::Base.configurations.primary?(connection.pool.db_config.name) + Gitlab::Database::SchemaVersionFiles.load_all + else + result + end end end end diff --git a/lib/gitlab/gon_helper.rb b/lib/gitlab/gon_helper.rb index 14f9c7f2191..8f2ba71e9ff 100644 --- a/lib/gitlab/gon_helper.rb +++ b/lib/gitlab/gon_helper.rb @@ -23,6 +23,7 @@ module Gitlab gon.gitlab_url = Gitlab.config.gitlab.url gon.revision = Gitlab.revision + gon.feature_category = Gitlab::ApplicationContext.current_context_attribute(:feature_category).presence gon.gitlab_logo = ActionController::Base.helpers.asset_path('gitlab_logo.png') gon.sprite_icons = IconsHelper.sprite_icon_path gon.sprite_file_icons = IconsHelper.sprite_file_icons_path diff --git a/lib/gitlab/reference_extractor.rb b/lib/gitlab/reference_extractor.rb index d7501fc7068..547549361be 100644 --- a/lib/gitlab/reference_extractor.rb +++ b/lib/gitlab/reference_extractor.rb @@ -24,8 +24,8 @@ module Gitlab super(text, context.merge(project: project)) end - def references(type) - refs = super(type, project, current_user) + def references(type, ids_only: false) + refs = super(type, project, current_user, ids_only: ids_only) @stateful_not_visible_counter += refs[:not_visible].count refs[:visible] @@ -41,6 +41,12 @@ module Gitlab define_method(type.to_s.pluralize) do @references[type] ||= references(type) end + + if %w(mentioned_user mentioned_group mentioned_project).include?(type.to_s) + define_method("#{type}_ids") do + @references[type] ||= references(type, ids_only: true) + end + end end def issues diff --git a/locale/gitlab.pot b/locale/gitlab.pot index 39837e1768e..c44dab892bd 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -35661,6 +35661,9 @@ msgstr "" msgid "ValueStreamAnalyticsStage|We don't have enough data to show this stage." msgstr "" +msgid "ValueStreamAnalytics|%{stageCount} items" +msgstr "" + msgid "ValueStreamAnalytics|%{value}M" msgstr "" diff --git a/spec/experiments/application_experiment_spec.rb b/spec/experiments/application_experiment_spec.rb index 2d2b911749b..25e91dfdedd 100644 --- a/spec/experiments/application_experiment_spec.rb +++ b/spec/experiments/application_experiment_spec.rb @@ -3,11 +3,10 @@ require 'spec_helper' RSpec.describe ApplicationExperiment, :experiment do - subject { described_class.new('namespaced/stub') } + subject { described_class.new('namespaced/stub', **context) } - let(:feature_definition) do - { name: 'namespaced_stub', type: 'experiment', group: 'group::adoption', default_enabled: false } - end + let(:context) { {} } + let(:feature_definition) { { name: 'namespaced_stub', type: 'experiment', default_enabled: false } } around do |example| Feature::Definition.definitions[:namespaced_stub] = Feature::Definition.new('namespaced_stub.yml', feature_definition) @@ -25,7 +24,7 @@ RSpec.describe ApplicationExperiment, :experiment do expect { experiment('namespaced/stub') { } }.not_to raise_error end - describe "enabled" do + describe "#enabled?" do before do allow(subject).to receive(:enabled?).and_call_original @@ -57,103 +56,100 @@ RSpec.describe ApplicationExperiment, :experiment do end end - describe "publishing results" do - it "doesn't record, track or push data to the client if we shouldn't track", :snowplow do + describe "#publish" do + it "doesn't track or publish to the client or database if we can't track", :snowplow do allow(subject).to receive(:should_track?).and_return(false) - subject.record! - expect(subject).not_to receive(:record_experiment) - expect(subject).not_to receive(:track) - expect(Gon).not_to receive(:push) + expect(subject).not_to receive(:publish_to_client) + expect(subject).not_to receive(:publish_to_database) - subject.publish(:action) + subject.publish expect_no_snowplow_event end - describe 'recording the experiment' do - it 'does not record the experiment if we do not tell it to' do - expect(subject).not_to receive(:record_experiment) - - subject.publish - end - - it 'records the experiment if we tell it to' do - subject.record! - - expect(subject).to receive(:record_experiment) - - subject.publish - end - end - it "tracks the assignment" do expect(subject).to receive(:track).with(:assignment) subject.publish end - it "pushes the experiment knowledge into the client using Gon" do - expect(Gon).to receive(:push).with({ experiment: { 'namespaced/stub' => subject.signature } }, true) + it "publishes the to the client" do + expect(subject).to receive(:publish_to_client) subject.publish end - it "handles when Gon raises exceptions (like when it can't be pushed into)" do - expect(Gon).to receive(:push).and_raise(NoMethodError) - - expect { subject.publish }.not_to raise_error - end - end - - it "can exclude from within the block" do - expect(described_class.new('namespaced/stub') { |e| e.exclude! }).to be_excluded - end - - describe 'recording the experiment subject' do - using RSpec::Parameterized::TableSyntax - - subject { described_class.new('namespaced/stub', nil, **context) } - - before do + it "publishes to the database if we've opted for that" do subject.record! + + expect(subject).to receive(:publish_to_database) + + subject.publish end - context 'when providing a compatible context' do - where(:context_key, :object_type) do - :namespace | :namespace - :group | :namespace - :project | :project - :user | :user - :actor | :user + describe "#publish_to_client" do + it "adds the data into Gon" do + signature = { key: '86208ac54ca798e11f127e8b23ec396a', variant: 'control' } + expect(Gon).to receive(:push).with({ experiment: { 'namespaced/stub' => hash_including(signature) } }, true) + + subject.publish_to_client end - with_them do - let(:context) { { context_key => build(object_type) }} + it "handles when Gon raises exceptions (like when it can't be pushed into)" do + expect(Gon).to receive(:push).and_raise(NoMethodError) - it 'records the experiment and the experiment subject from the context' do - expect { subject.publish }.to change(Experiment, :count).by(1) + expect { subject.publish_to_client }.not_to raise_error + end + end - expect(Experiment.last.name).to eq('namespaced/stub') - expect(ExperimentSubject.last.send(object_type)).to eq(context[context_key]) + describe "#publish_to_database" do + using RSpec::Parameterized::TableSyntax + let(:context) { { context_key => context_value }} + + before do + subject.record! + end + + context "when there's a usable subject" do + where(:context_key, :context_value, :object_type) do + :namespace | build(:namespace) | :namespace + :group | build(:namespace) | :namespace + :project | build(:project) | :project + :user | build(:user) | :user + :actor | build(:user) | :user + end + + with_them do + it "creates an experiment and experiment subject record" do + expect { subject.publish_to_database }.to change(Experiment, :count).by(1) + + expect(Experiment.last.name).to eq('namespaced/stub') + expect(ExperimentSubject.last.send(object_type)).to eq(context[context_key]) + end end end - end - context 'when providing an incompatible or no context' do - where(context_hash: [{ foo: :bar }, {}]) + context "when there's not a usable subject" do + where(:context_key, :context_value) do + :namespace | nil + :foo | :bar + end - with_them do - let(:context) { context_hash } + with_them do + it "doesn't create an experiment record" do + expect { subject.publish_to_database }.not_to change(Experiment, :count) + end - it 'does not record the experiment' do - expect { subject.publish }.not_to change(Experiment, :count) + it "doesn't create an experiment subject record" do + expect { subject.publish_to_database }.not_to change(ExperimentSubject, :count) + end end end end end - describe "tracking events", :snowplow do + describe "#track", :snowplow do it "doesn't track if we shouldn't track" do allow(subject).to receive(:should_track?).and_return(false) @@ -185,7 +181,13 @@ RSpec.describe ApplicationExperiment, :experiment do end end - describe "variant resolution" do + describe "#key_for" do + it "generates MD5 hashes" do + expect(subject.key_for(foo: :bar)).to eq('6f9ac12afdb9b58c2f19a136d09f9153') + end + end + + context "when resolving variants" do it "uses the default value as specified in the yaml" do expect(Feature).to receive(:enabled?).with('namespaced_stub', subject, type: :experiment, default_enabled: :yaml) diff --git a/spec/features/projects/releases/user_views_edit_release_spec.rb b/spec/features/projects/releases/user_views_edit_release_spec.rb index 024c0a227c5..561b283ee15 100644 --- a/spec/features/projects/releases/user_views_edit_release_spec.rb +++ b/spec/features/projects/releases/user_views_edit_release_spec.rb @@ -4,9 +4,11 @@ require 'spec_helper' RSpec.describe 'User edits Release', :js do let_it_be(:project) { create(:project, :repository) } - let_it_be(:release) { create(:release, :with_milestones, milestones_count: 1, project: project, name: 'The first release' ) } let_it_be(:user) { create(:user) } + let(:release) { create(:release, :with_milestones, milestones_count: 1, project: project, name: 'The first release' ) } + let(:release_link) { create(:release_link, release: release) } + before do project.add_developer(user) @@ -68,6 +70,14 @@ RSpec.describe 'User edits Release', :js do expect(release.description).to eq('Updated Release notes') end + it 'does not affect the asset link' do + fill_out_form_and_click 'Save changes' + + expected_filepath = release_link.filepath + release_link.reload + expect(release_link.filepath).to eq(expected_filepath) + end + it 'redirects to the previous page when "Cancel" is clicked when the url includes a back_url query parameter' do back_path = project_releases_path(project, params: { page: 2 }) visit edit_project_release_path(project, release, params: { back_url: back_path }) diff --git a/spec/frontend/cycle_analytics/formatted_stage_count_spec.js b/spec/frontend/cycle_analytics/formatted_stage_count_spec.js new file mode 100644 index 00000000000..19f1a7187b3 --- /dev/null +++ b/spec/frontend/cycle_analytics/formatted_stage_count_spec.js @@ -0,0 +1,34 @@ +import { shallowMount } from '@vue/test-utils'; +import Component from '~/cycle_analytics/components/formatted_stage_count.vue'; + +describe('Formatted Stage Count', () => { + let wrapper = null; + + const createComponent = (stageCount = null) => { + wrapper = shallowMount(Component, { + propsData: { + stageCount, + }, + }); + }; + + beforeEach(() => { + createComponent(); + }); + + afterEach(() => { + wrapper.destroy(); + }); + + it.each` + stageCount | expectedOutput + ${null} | ${'-'} + ${1} | ${'1 item'} + ${10} | ${'10 items'} + ${1000} | ${'1000 items'} + ${1001} | ${'1000+ items'} + `('returns "$expectedOutput" for stageCount=$stageCount', ({ stageCount, expectedOutput }) => { + createComponent(stageCount); + expect(wrapper.text()).toContain(expectedOutput); + }); +}); diff --git a/spec/frontend/releases/__snapshots__/util_spec.js.snap b/spec/frontend/releases/__snapshots__/util_spec.js.snap index 0de2ec5cd89..b2580d47549 100644 --- a/spec/frontend/releases/__snapshots__/util_spec.js.snap +++ b/spec/frontend/releases/__snapshots__/util_spec.js.snap @@ -212,24 +212,28 @@ Object { "count": undefined, "links": Array [ Object { + "directAssetPath": "/binaries/awesome-app-3", "id": "gid://gitlab/Releases::Link/13", "linkType": "image", "name": "Image", "url": "https://example.com/image", }, Object { + "directAssetPath": "/binaries/awesome-app-2", "id": "gid://gitlab/Releases::Link/12", "linkType": "package", "name": "Package", "url": "https://example.com/package", }, Object { + "directAssetPath": "/binaries/awesome-app-1", "id": "gid://gitlab/Releases::Link/11", "linkType": "runbook", "name": "Runbook", "url": "http://localhost/releases-namespace/releases-project/runbook", }, Object { + "directAssetPath": "/binaries/linux-amd64", "id": "gid://gitlab/Releases::Link/10", "linkType": "other", "name": "linux-amd64 binaries", diff --git a/spec/frontend/sentry/index_spec.js b/spec/frontend/sentry/index_spec.js index 13b9b9e909c..d1f098112e8 100644 --- a/spec/frontend/sentry/index_spec.js +++ b/spec/frontend/sentry/index_spec.js @@ -7,6 +7,8 @@ describe('SentryConfig options', () => { const gitlabUrl = 'gitlabUrl'; const environment = 'test'; const revision = 'revision'; + const featureCategory = 'my_feature_category'; + let indexReturnValue; beforeEach(() => { @@ -16,6 +18,7 @@ describe('SentryConfig options', () => { current_user_id: currentUserId, gitlab_url: gitlabUrl, revision, + feature_category: featureCategory, }; process.env.HEAD_COMMIT_SHA = revision; @@ -34,6 +37,7 @@ describe('SentryConfig options', () => { release: revision, tags: { revision, + feature_category: featureCategory, }, }); }); diff --git a/spec/frontend/sentry/sentry_config_spec.js b/spec/frontend/sentry/sentry_config_spec.js index 1f5097ef2a8..9f67b681b8d 100644 --- a/spec/frontend/sentry/sentry_config_spec.js +++ b/spec/frontend/sentry/sentry_config_spec.js @@ -72,11 +72,13 @@ describe('SentryConfig', () => { release: 'revision', tags: { revision: 'revision', + feature_category: 'my_feature_category', }, }; beforeEach(() => { jest.spyOn(Sentry, 'init').mockImplementation(); + jest.spyOn(Sentry, 'setTags').mockImplementation(); sentryConfig.options = options; sentryConfig.IGNORE_ERRORS = 'ignore_errors'; @@ -89,7 +91,6 @@ describe('SentryConfig', () => { expect(Sentry.init).toHaveBeenCalledWith({ dsn: options.dsn, release: options.release, - tags: options.tags, sampleRate: 0.95, whitelistUrls: options.whitelistUrls, environment: 'test', @@ -98,6 +99,10 @@ describe('SentryConfig', () => { }); }); + it('should call Sentry.setTags', () => { + expect(Sentry.setTags).toHaveBeenCalledWith(options.tags); + }); + it('should set environment from options', () => { sentryConfig.options.environment = 'development'; @@ -106,7 +111,6 @@ describe('SentryConfig', () => { expect(Sentry.init).toHaveBeenCalledWith({ dsn: options.dsn, release: options.release, - tags: options.tags, sampleRate: 0.95, whitelistUrls: options.whitelistUrls, environment: 'development', diff --git a/spec/graphql/types/release_asset_link_type_spec.rb b/spec/graphql/types/release_asset_link_type_spec.rb index 6800d5459c4..0c903b8d27a 100644 --- a/spec/graphql/types/release_asset_link_type_spec.rb +++ b/spec/graphql/types/release_asset_link_type_spec.rb @@ -7,7 +7,7 @@ RSpec.describe GitlabSchema.types['ReleaseAssetLink'] do it 'has the expected fields' do expected_fields = %w[ - id name url external link_type direct_asset_url + id name url external link_type direct_asset_url direct_asset_path ] expect(described_class).to include_graphql_fields(*expected_fields) diff --git a/spec/graphql/types/snippets/blob_type_spec.rb b/spec/graphql/types/snippets/blob_type_spec.rb index 60c0db8e551..e20b001ba7f 100644 --- a/spec/graphql/types/snippets/blob_type_spec.rb +++ b/spec/graphql/types/snippets/blob_type_spec.rb @@ -6,7 +6,7 @@ RSpec.describe GitlabSchema.types['SnippetBlob'] do include GraphqlHelpers it 'has the correct fields' do - expected_fields = [:rich_data, :plain_data, + expected_fields = [:rich_data, :plain_data, :raw_plain_data, :raw_path, :size, :binary, :name, :path, :simple_viewer, :rich_viewer, :mode, :external_storage, :rendered_as_text] @@ -18,6 +18,7 @@ RSpec.describe GitlabSchema.types['SnippetBlob'] do { 'richData' => be_nullable, 'plainData' => be_nullable, + 'rawPlainData' => be_nullable, 'rawPath' => be_non_null, 'size' => be_non_null, 'binary' => be_non_null, diff --git a/spec/lib/banzai/reference_parser/base_parser_spec.rb b/spec/lib/banzai/reference_parser/base_parser_spec.rb index 18d8418ca23..095500cdc53 100644 --- a/spec/lib/banzai/reference_parser/base_parser_spec.rb +++ b/spec/lib/banzai/reference_parser/base_parser_spec.rb @@ -78,12 +78,31 @@ RSpec.describe Banzai::ReferenceParser::BaseParser do describe '#referenced_by' do context 'when references_relation is implemented' do - it 'returns a collection of objects' do - links = Nokogiri::HTML.fragment("") - .children + context 'and ids_only is set to false' do + it 'returns a collection of objects' do + links = Nokogiri::HTML.fragment("") + .children - expect(subject).to receive(:references_relation).and_return(User) - expect(subject.referenced_by(links)).to eq([user]) + expect(subject).to receive(:references_relation).and_return(User) + expect(subject.referenced_by(links)).to eq([user]) + end + end + + context 'and ids_only is set to true' do + it 'returns a collection of id values without performing a db query' do + links = Nokogiri::HTML.fragment("").children + + expect(subject).not_to receive(:references_relation) + expect(subject.referenced_by(links, ids_only: true)).to eq(%w(1 2)) + end + + context 'and the html fragment does not contain any attributes' do + it 'returns an empty array' do + links = Nokogiri::HTML.fragment("no links").children + + expect(subject.referenced_by(links, ids_only: true)).to eq([]) + end + end end end @@ -188,7 +207,7 @@ RSpec.describe Banzai::ReferenceParser::BaseParser do dummy = Class.new(described_class) do self.reference_type = :test - def gather_references(nodes) + def gather_references(nodes, ids_only: false) nodes end end @@ -222,7 +241,7 @@ RSpec.describe Banzai::ReferenceParser::BaseParser do nodes.select { |n| n.id > 5 } end - def referenced_by(nodes) + def referenced_by(nodes, ids_only: false) nodes.map(&:id) end end diff --git a/spec/lib/gitlab/database/postgresql_adapter/dump_schema_versions_mixin_spec.rb b/spec/lib/gitlab/database/postgresql_adapter/dump_schema_versions_mixin_spec.rb index ca9f4af9187..fc6a235eabd 100644 --- a/spec/lib/gitlab/database/postgresql_adapter/dump_schema_versions_mixin_spec.rb +++ b/spec/lib/gitlab/database/postgresql_adapter/dump_schema_versions_mixin_spec.rb @@ -4,30 +4,61 @@ require 'spec_helper' RSpec.describe Gitlab::Database::PostgresqlAdapter::DumpSchemaVersionsMixin do let(:schema_migration) { double('schema_migration', all_versions: versions) } + let(:db_name) { 'primary' } + let(:versions) { %w(5 2 1000 200 4 93 2) } - let(:instance) do - Object.new.extend(described_class) + let(:instance_class) do + klass = Class.new do + def dump_schema_information + original_dump_schema_information + end + + def original_dump_schema_information + end + end + + klass.prepend(described_class) + + klass end + let(:instance) { instance_class.new } + before do allow(instance).to receive(:schema_migration).and_return(schema_migration) + + # pool is from ActiveRecord::ConnectionAdapters::PostgreSQLAdapter + allow(instance).to receive_message_chain(:pool, :db_config, :name).and_return(db_name) end - context 'when version files exist' do - let(:versions) { %w(5 2 1000 200 4 93 2) } + context 'when database name is primary' do + context 'when version files exist' do + it 'touches version files' do + expect(Gitlab::Database::SchemaVersionFiles).to receive(:touch_all).with(versions) + expect(instance).not_to receive(:original_dump_schema_information) - it 'touches version files' do - expect(Gitlab::Database::SchemaVersionFiles).to receive(:touch_all).with(versions) + instance.dump_schema_information + end + end - instance.dump_schema_information + context 'when version files do not exist' do + let(:versions) { [] } + + it 'does not touch version files' do + expect(Gitlab::Database::SchemaVersionFiles).not_to receive(:touch_all) + expect(instance).not_to receive(:original_dump_schema_information) + + instance.dump_schema_information + end end end - context 'when version files do not exist' do - let(:versions) { [] } + context 'when database name is ci' do + let(:db_name) { 'ci' } it 'does not touch version files' do expect(Gitlab::Database::SchemaVersionFiles).not_to receive(:touch_all) + expect(instance).to receive(:original_dump_schema_information) instance.dump_schema_information end diff --git a/spec/lib/gitlab/database/postgresql_database_tasks/load_schema_versions_mixin_spec.rb b/spec/lib/gitlab/database/postgresql_database_tasks/load_schema_versions_mixin_spec.rb new file mode 100644 index 00000000000..8bd4ea66200 --- /dev/null +++ b/spec/lib/gitlab/database/postgresql_database_tasks/load_schema_versions_mixin_spec.rb @@ -0,0 +1,49 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Gitlab::Database::PostgresqlDatabaseTasks::LoadSchemaVersionsMixin do + let(:db_name) { 'primary' } + + let(:instance_class) do + klass = Class.new do + def structure_load + original_structure_load + end + + def original_structure_load + end + end + + klass.prepend(described_class) + + klass + end + + let(:instance) { instance_class.new } + + before do + # connection is available in ActiveRecord::Tasks::PostgreSQLDatabaseTasks + allow(instance).to receive_message_chain(:connection, :pool, :db_config, :name).and_return(db_name) + end + + context 'when database is primary' do + it 'loads version files' do + expect(Gitlab::Database::SchemaVersionFiles).to receive(:load_all) + expect(instance).to receive(:original_structure_load) + + instance.structure_load + end + end + + context 'when the database is ci' do + let(:db_name) { 'ci' } + + it 'does not load version files' do + expect(Gitlab::Database::SchemaVersionFiles).not_to receive(:load_all) + expect(instance).to receive(:original_structure_load) + + instance.structure_load + end + end +end diff --git a/spec/lib/gitlab/database_spec.rb b/spec/lib/gitlab/database_spec.rb index 2e7b2c344f1..d71befccdfa 100644 --- a/spec/lib/gitlab/database_spec.rb +++ b/spec/lib/gitlab/database_spec.rb @@ -41,6 +41,45 @@ RSpec.describe Gitlab::Database do end end + describe '.has_config?' do + context 'two tier database config' do + before do + allow(Gitlab::Application).to receive_message_chain(:config, :database_configuration, :[]).with(Rails.env) + .and_return({ "adapter" => "postgresql", "database" => "gitlabhq_test" }) + end + + it 'returns false for primary' do + expect(described_class.has_config?(:primary)).to eq(false) + end + + it 'returns false for ci' do + expect(described_class.has_config?(:ci)).to eq(false) + end + end + + context 'three tier database config' do + before do + allow(Gitlab::Application).to receive_message_chain(:config, :database_configuration, :[]).with(Rails.env) + .and_return({ + "primary" => { "adapter" => "postgresql", "database" => "gitlabhq_test" }, + "ci" => { "adapter" => "postgresql", "database" => "gitlabhq_test_ci" } + }) + end + + it 'returns true for primary' do + expect(described_class.has_config?(:primary)).to eq(true) + end + + it 'returns true for ci' do + expect(described_class.has_config?(:ci)).to eq(true) + end + + it 'returns false for non-existent' do + expect(described_class.has_config?(:nonexistent)).to eq(false) + end + end + end + describe '.adapter_name' do it 'returns the name of the adapter' do expect(described_class.adapter_name).to be_an_instance_of(String) diff --git a/spec/migrations/active_record/schema_spec.rb b/spec/migrations/active_record/schema_spec.rb index 8199f55f5fc..4a505c51a16 100644 --- a/spec/migrations/active_record/schema_spec.rb +++ b/spec/migrations/active_record/schema_spec.rb @@ -7,10 +7,10 @@ require 'spec_helper' RSpec.describe ActiveRecord::Schema, schema: :latest do let(:all_migrations) do - migrations_paths = %w[db/migrate db/post_migrate] - .map { |path| Rails.root.join(*path, '*') } + migrations_directories = %w[db/migrate db/post_migrate].map { |path| Rails.root.join(path).to_s } + migrations_paths = migrations_directories.map { |path| File.join(path, '*') } - migrations = Dir[*migrations_paths] + migrations = Dir[*migrations_paths] - migrations_directories migrations.map { |migration| File.basename(migration).split('_').first.to_i }.sort end diff --git a/spec/presenters/blob_presenter_spec.rb b/spec/presenters/blob_presenter_spec.rb index 38bdf3b9364..466a2b55e76 100644 --- a/spec/presenters/blob_presenter_spec.rb +++ b/spec/presenters/blob_presenter_spec.rb @@ -121,16 +121,26 @@ RSpec.describe BlobPresenter do end end - describe '#plain_data' do + describe '#raw_plain_data' do let(:blob) { repository.blob_at('HEAD', file) } - subject { described_class.new(blob).plain_data } + context 'when blob is text' do + let(:file) { 'files/ruby/popen.rb' } + + it 'does not include html in the content' do + expect(presenter.raw_plain_data.include?('')).to be_falsey + end + end + end + + describe '#plain_data' do + let(:blob) { repository.blob_at('HEAD', file) } context 'when blob is binary' do let(:file) { 'files/images/logo-black.png' } it 'returns nil' do - expect(subject).to be_nil + expect(presenter.plain_data).to be_nil end end @@ -138,7 +148,7 @@ RSpec.describe BlobPresenter do let(:file) { 'README.md' } it 'returns plain content' do - expect(subject).to include('') + expect(presenter.plain_data).to include('') end end @@ -146,7 +156,7 @@ RSpec.describe BlobPresenter do let(:file) { 'files/ruby/regex.rb' } it 'returns highlighted syntax content' do - expect(subject) + expect(presenter.plain_data) .to include 'module Gitlab' end end @@ -155,7 +165,7 @@ RSpec.describe BlobPresenter do let(:file) { 'LICENSE' } it 'returns plain text highlighted content' do - expect(subject).to include('The MIT License (MIT)') + expect(presenter.plain_data).to include('The MIT License (MIT)') end end end diff --git a/spec/presenters/snippet_blob_presenter_spec.rb b/spec/presenters/snippet_blob_presenter_spec.rb index 42eca6b5a49..1a5130dcdf6 100644 --- a/spec/presenters/snippet_blob_presenter_spec.rb +++ b/spec/presenters/snippet_blob_presenter_spec.rb @@ -120,6 +120,27 @@ RSpec.describe SnippetBlobPresenter do end end + describe '#raw_plain_data' do + context "with a plain file" do + subject { described_class.new(blob, current_user: user) } + + it 'shows raw data for non binary files' do + expect(subject.raw_plain_data).to eq(blob.data) + end + end + + context "with a binary file" do + let(:file) { 'files/images/logo-black.png' } + let(:blob) { blob_at(file) } + + subject { described_class.new(blob, current_user: user) } + + it 'returns nil' do + expect(subject.raw_plain_data).to be_nil + end + end + end + describe '#raw_url' do subject { described_class.new(blob, current_user: user).raw_url } diff --git a/spec/requests/api/graphql/mutations/packages/destroy_package_spec.rb b/spec/requests/api/graphql/mutations/packages/destroy_spec.rb similarity index 100% rename from spec/requests/api/graphql/mutations/packages/destroy_package_spec.rb rename to spec/requests/api/graphql/mutations/packages/destroy_spec.rb diff --git a/spec/services/issues/update_service_spec.rb b/spec/services/issues/update_service_spec.rb index b95d94e3784..2f7aaf3f7f8 100644 --- a/spec/services/issues/update_service_spec.rb +++ b/spec/services/issues/update_service_spec.rb @@ -488,6 +488,21 @@ RSpec.describe Issues::UpdateService, :mailer do end end end + + it 'verifies the number of queries' do + update_issue(description: "- [ ] Task 1 #{user.to_reference}") + + baseline = ActiveRecord::QueryRecorder.new do + update_issue(description: "- [x] Task 1 #{user.to_reference}") + end + + recorded = ActiveRecord::QueryRecorder.new do + update_issue(description: "- [x] Task 1 #{user.to_reference}\n- [ ] Task 2 #{user.to_reference}") + end + + expect(recorded.count).to eq(baseline.count - 1) + expect(recorded.cached_count).to eq(0) + end end context 'when description changed' do