Commit ab50721f authored by Shinya Maeda's avatar Shinya Maeda

Merge branch 'mo-add-syntax-build-tags-limit' into 'master'

Prevents pipeline creation for builds with more than 50 tags

See merge request gitlab-org/gitlab!68380
parents bf553406 0ba82568
---
name: ci_build_tags_limit
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/68380
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/338929
milestone: '14.2'
type: development
group: group::pipeline execution
default_enabled: false
......@@ -1885,6 +1885,9 @@ variables:
- echo "Hello runner selector feature"
```
NOTE:
In [GitLab 14.3](https://gitlab.com/gitlab-org/gitlab/-/issues/338479) and later, the number of tags must be less than `50`.
### `allow_failure`
Use `allow_failure` when you want to let a job fail without impacting the rest of the CI
......
......@@ -53,7 +53,7 @@ module Gitlab
description: 'Set retry default value.',
inherit: false
entry :tags, ::Gitlab::Config::Entry::ArrayOfStrings,
entry :tags, Entry::Tags,
description: 'Set the default tags.',
inherit: false
......
......@@ -85,7 +85,7 @@ module Gitlab
description: 'Retry configuration for this job.',
inherit: true
entry :tags, ::Gitlab::Config::Entry::ArrayOfStrings,
entry :tags, Entry::Tags,
description: 'Set the tags.',
inherit: true
......
# frozen_string_literal: true
module Gitlab
module Ci
class Config
module Entry
##
# Entry that represents an array of tags.
#
class Tags < ::Gitlab::Config::Entry::Node
include ::Gitlab::Config::Entry::Validatable
TAGS_LIMIT = 50
validations do
validates :config, array_of_strings: true
validate do
next unless ::Feature.enabled?(:ci_build_tags_limit, default_enabled: :yaml)
if config.is_a?(Array) && config.size >= TAGS_LIMIT
errors.add(:config, _("must be less than the limit of %{tag_limit} tags") % { tag_limit: TAGS_LIMIT })
end
end
end
end
end
end
end
end
......@@ -39962,6 +39962,9 @@ msgstr ""
msgid "must be inside the fork network"
msgstr ""
msgid "must be less than the limit of %{tag_limit} tags"
msgstr ""
msgid "must be unique by status and elapsed time within a policy"
msgstr ""
......
......@@ -618,6 +618,29 @@ RSpec.describe Gitlab::Ci::Config::Entry::Job do
end
end
end
context 'when job is using tags' do
context 'when limit is reached' do
let(:tags) { Array.new(100) { |i| "tag-#{i}" } }
let(:config) { { tags: tags, script: 'test' } }
it 'returns error', :aggregate_failures do
expect(entry).not_to be_valid
expect(entry.errors)
.to include "tags config must be less than the limit of #{Gitlab::Ci::Config::Entry::Tags::TAGS_LIMIT} tags"
end
end
context 'when limit is not reached' do
let(:config) { { tags: %w[tag1 tag2], script: 'test' } }
it 'returns a valid entry', :aggregate_failures do
expect(entry).to be_valid
expect(entry.errors).to be_empty
expect(entry.tags).to eq(%w[tag1 tag2])
end
end
end
end
describe '#manual_action?' do
......
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Gitlab::Ci::Config::Entry::Tags do
let(:entry) { described_class.new(config) }
describe 'validation' do
context 'when tags config value is correct' do
let(:config) { %w[tag1 tag2] }
describe '#value' do
it 'returns tags configuration' do
expect(entry.value).to eq config
end
end
describe '#valid?' do
it 'is valid' do
expect(entry).to be_valid
end
end
end
context 'when entry value is not correct' do
describe '#errors' do
context 'when tags config is not an array of strings' do
let(:config) { [1, 2] }
it 'reports error' do
expect(entry.errors)
.to include 'tags config should be an array of strings'
end
end
context 'when tags limit is reached' do
let(:config) { Array.new(50) {|i| "tag-#{i}" } }
context 'when ci_build_tags_limit is enabled' do
before do
stub_feature_flags(ci_build_tags_limit: true)
end
it 'reports error' do
expect(entry.errors)
.to include "tags config must be less than the limit of #{described_class::TAGS_LIMIT} tags"
end
end
context 'when ci_build_tags_limit is disabled' do
before do
stub_feature_flags(ci_build_tags_limit: false)
end
it 'does not report an error' do
expect(entry.errors).to be_empty
end
end
end
end
end
end
end
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Ci::CreatePipelineService do
describe 'tags:' do
let_it_be(:project) { create(:project, :repository) }
let_it_be(:user) { project.owner }
let(:ref) { 'refs/heads/master' }
let(:source) { :push }
let(:service) { described_class.new(project, user, { ref: ref }) }
let(:pipeline) { service.execute(source).payload }
before do
stub_ci_pipeline_yaml_file(config)
end
context 'with valid config' do
let(:config) { YAML.dump({ test: { script: 'ls', tags: %w[tag1 tag2] } }) }
it 'creates a pipeline', :aggregate_failures do
expect(pipeline).to be_created_successfully
expect(pipeline.builds.first.tag_list).to eq(%w[tag1 tag2])
end
end
context 'with too many tags' do
let(:tags) { Array.new(50) {|i| "tag-#{i}" } }
let(:config) { YAML.dump({ test: { script: 'ls', tags: tags } }) }
it 'creates a pipeline without builds', :aggregate_failures do
expect(pipeline).not_to be_created_successfully
expect(pipeline.builds).to be_empty
expect(pipeline.yaml_errors).to eq("jobs:test:tags config must be less than the limit of #{Gitlab::Ci::Config::Entry::Tags::TAGS_LIMIT} tags")
end
end
end
end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment