Skip to content
Snippets Groups Projects
Commit 0ba82568 authored by Maxime Orefice's avatar Maxime Orefice Committed by Shinya Maeda
Browse files

Prevents pipeline creation for builds with more than 50 tags

parent 4ba24381
No related branches found
No related tags found
No related merge requests found
---
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
Loading
Loading
@@ -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
Loading
Loading
Loading
Loading
@@ -53,7 +53,7 @@ class Default < ::Gitlab::Config::Entry::Node
description: 'Set retry default value.',
inherit: false
 
entry :tags, ::Gitlab::Config::Entry::ArrayOfStrings,
entry :tags, Entry::Tags,
description: 'Set the default tags.',
inherit: false
 
Loading
Loading
Loading
Loading
@@ -85,7 +85,7 @@ class Job < ::Gitlab::Config::Entry::Node
description: 'Retry configuration for this job.',
inherit: true
 
entry :tags, ::Gitlab::Config::Entry::ArrayOfStrings,
entry :tags, Entry::Tags,
description: 'Set the tags.',
inherit: true
 
Loading
Loading
# 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
Loading
Loading
@@ -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 ""
 
Loading
Loading
Loading
Loading
@@ -618,6 +618,29 @@
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
Loading
Loading
# 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
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment