Commit 6c8fd3fa authored by Kamil Trzciński's avatar Kamil Trzciński

Merge branch '40994-expose-features-as-ci-cd-variable' into 'master'

Expose GITLAB_FEATURES as CI/CD variable (fixes #40994)

Closes gitlab-ce#40994

See merge request gitlab-org/gitlab-ee!4393
parents 70b40180 8e31ff78
......@@ -84,6 +84,7 @@ future GitLab releases.**
| **GITLAB_USER_EMAIL** | 8.12 | all | The email of the user who started the job |
| **GITLAB_USER_LOGIN** | 10.0 | all | The login username of the user who started the job |
| **GITLAB_USER_NAME** | 10.0 | all | The real name of the user who started the job |
| **GITLAB_FEATURES** | 10.6 | all | The comma separated list of licensed features available for your instance and plan |
| **RESTORE_CACHE_ATTEMPTS** | 8.15 | 1.9 | Number of attempts to restore the cache running a job |
## 9.0 Renaming
......
......@@ -64,6 +64,15 @@ module EE
succeeded
end
override :features
def features
return super unless License.current
License.current.features.select do |feature|
License.global_feature?(feature) || feature_available?(feature)
end
end
# Checks features (i.e. https://about.gitlab.com/products/) availabily
# for a given Namespace plan. This method should consider ancestor groups
# being licensed.
......
......@@ -153,7 +153,7 @@ class License < ActiveRecord::Base
end
def plans_with_feature(feature)
if GLOBAL_FEATURES.include?(feature)
if global_feature?(feature)
raise ArgumentError, "Use `License.feature_available?` for features that cannot be restricted to only a subset of projects or namespaces"
end
......@@ -187,6 +187,10 @@ class License < ActiveRecord::Base
license
end
def global_feature?(feature)
GLOBAL_FEATURES.include?(feature)
end
end
def data_filename
......
require 'spec_helper'
describe Ci::Build do
let(:project) { create(:project, :repository) }
set(:group) { create(:group, :access_requestable, plan: :bronze_plan) }
let(:project) { create(:project, :repository, group: group) }
let(:pipeline) do
create(:ci_pipeline, project: project,
......@@ -125,6 +126,14 @@ describe Ci::Build do
it { is_expected.not_to include(environment_varialbe) }
end
context 'when there is a plan for the group' do
it 'GITLAB_FEATURES should include the features for that plan' do
is_expected.to include({ key: 'GITLAB_FEATURES', value: anything, public: true })
features_variable = subject.find { |v| v[:key] == 'GITLAB_FEATURES' }
expect(features_variable[:value]).to include('multiple_ldap_servers')
end
end
end
end
......
......@@ -122,6 +122,76 @@ describe Namespace do
end
end
describe '#features' do
let(:plan_license) { :free_plan }
let(:group) { create(:group, plan: plan_license) }
let(:global_license) { create(:license) }
before do
allow(License).to receive(:current).and_return(global_license)
allow(global_license).to receive(:features).and_return([
:epics, # Gold only
:service_desk, # Silver and up
:audit_events, # Bronze and up
:geo, # Global feature, should not be checked at namespace level
])
end
subject { group.features }
context 'when the namespace should be checked' do
before do
enable_namespace_license_check!
end
context 'when bronze' do
let(:plan_license) { :bronze_plan }
it 'filters for bronze features' do
is_expected.to contain_exactly(:audit_events, :geo)
end
end
context 'when silver' do
let(:plan_license) { :silver_plan }
it 'filters for silver features' do
is_expected.to contain_exactly(:service_desk, :audit_events, :geo)
end
end
context 'when gold' do
let(:plan_license) { :gold_plan }
it 'filters for gold features' do
is_expected.to contain_exactly(:epics, :service_desk, :audit_events, :geo)
end
end
context 'when free plan' do
let(:plan_license) { :free_plan }
it 'filters out paid features' do
is_expected.to contain_exactly(:geo)
end
end
end
context 'when namespace should not be checked' do
it 'includes all features in global license' do
is_expected.to contain_exactly(:epics, :service_desk, :audit_events, :geo)
end
end
context 'when there is no license' do
before do
allow(License).to receive(:current).and_return(nil)
end
it { is_expected.to be_empty }
end
end
describe '#feature_available?' do
let(:plan_license) { :bronze_plan }
let(:group) { create(:group, plan: plan_license) }
......
......@@ -349,6 +349,22 @@ describe License do
end
end
end
describe '.global_feature?' do
subject { described_class.global_feature?(feature) }
context 'when it is a global feature' do
let(:feature) { :geo }
it { is_expected.to be(true) }
end
context 'when it is not a global feature' do
let(:feature) { :sast }
it { is_expected.to be(false) }
end
end
end
describe "#md5" do
......
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