Commit e056852f authored by Mario Celi's avatar Mario Celi

Iteration cadences feature flag checks for root ancestor too

For root groups that have the iteration_cadences feature flag
enabled. It becomes a problem for child groups to distinguish
one iteration from the other. This change enables the FF
for all children if enabled at the root_ancestor.
parent eb2022fe
......@@ -8,7 +8,6 @@ class Groups::BoardsController < Groups::ApplicationController
before_action :assign_endpoint_vars
before_action do
push_frontend_feature_flag(:board_multi_select, group, default_enabled: :yaml)
push_frontend_feature_flag(:iteration_cadences, group, default_enabled: :yaml)
push_frontend_feature_flag(:realtime_labels, group, default_enabled: :yaml)
experiment(:prominent_create_board_btn, subject: current_user) do |e|
e.control { }
......@@ -50,3 +49,5 @@ class Groups::BoardsController < Groups::ApplicationController
access_denied! unless can?(current_user, :read_issue_board, group)
end
end
Groups::BoardsController.prepend_mod
......@@ -33,7 +33,6 @@ class GroupsController < Groups::ApplicationController
before_action do
push_frontend_feature_flag(:vue_issues_list, @group, default_enabled: :yaml)
push_frontend_feature_flag(:iteration_cadences, @group, default_enabled: :yaml)
end
before_action :check_export_rate_limit!, only: [:export, :download_export]
......
......@@ -8,7 +8,6 @@ class Projects::BoardsController < Projects::ApplicationController
before_action :assign_endpoint_vars
before_action do
push_frontend_feature_flag(:board_multi_select, project, default_enabled: :yaml)
push_frontend_feature_flag(:iteration_cadences, project&.group, default_enabled: :yaml)
push_frontend_feature_flag(:realtime_labels, project&.group, default_enabled: :yaml)
experiment(:prominent_create_board_btn, subject: current_user) do |e|
e.control { }
......@@ -51,3 +50,5 @@ class Projects::BoardsController < Projects::ApplicationController
access_denied! unless can?(current_user, :read_issue_board, project)
end
end
Projects::BoardsController.prepend_mod
......@@ -40,7 +40,6 @@ class Projects::IssuesController < Projects::ApplicationController
before_action do
push_frontend_feature_flag(:vue_issues_list, project&.group, default_enabled: :yaml)
push_frontend_feature_flag(:iteration_cadences, project&.group, default_enabled: :yaml)
push_frontend_feature_flag(:contacts_autocomplete, project&.group, default_enabled: :yaml)
push_frontend_feature_flag(:markdown_continue_lists, project, default_enabled: :yaml)
push_frontend_feature_flag(:incident_timeline, project, default_enabled: :yaml)
......
......@@ -828,12 +828,7 @@ class Group < Namespace
end
def work_items_feature_flag_enabled?
actors = [root_ancestor]
actors << self if root_ancestor != self
actors.any? do |actor|
Feature.enabled?(:work_items, actor, default_enabled: :yaml)
end
feature_flag_enabled_for_self_or_ancestor?(:work_items)
end
# Check for enabled features, similar to `Project#feature_available?`
......@@ -849,6 +844,15 @@ class Group < Namespace
private
def feature_flag_enabled_for_self_or_ancestor?(feature_flag)
actors = [root_ancestor]
actors << self if root_ancestor != self
actors.any? do |actor|
::Feature.enabled?(feature_flag, actor, default_enabled: :yaml)
end
end
def max_member_access(user_ids)
Gitlab::SafeRequestLoader.execute(resource_key: max_member_access_for_resource_key(User),
resource_ids: user_ids,
......
# frozen_string_literal: true
module EE
module Groups
module BoardsController
extend ActiveSupport::Concern
prepended do
before_action do
push_force_frontend_feature_flag(:iteration_cadences, group&.iteration_cadences_feature_flag_enabled?)
end
end
end
end
end
......@@ -17,6 +17,7 @@ module EE
before_action do
push_frontend_feature_flag(:saas_user_caps_auto_approve_pending_users_on_cap_increase, @group, default_enabled: :yaml)
push_force_frontend_feature_flag(:iteration_cadences, @group&.iteration_cadences_feature_flag_enabled?)
end
feature_category :subgroups, [:restore]
......
# frozen_string_literal: true
module EE
module Projects
module BoardsController
extend ActiveSupport::Concern
prepended do
before_action do
push_force_frontend_feature_flag(
:iteration_cadences,
project&.group&.iteration_cadences_feature_flag_enabled?
)
end
end
end
end
end
......@@ -25,6 +25,13 @@ module EE
before_action :redirect_if_test_case, only: [:show]
before_action do
push_force_frontend_feature_flag(
:iteration_cadences,
project&.group&.iteration_cadences_feature_flag_enabled?
)
end
feature_category :team_planning, [:delete_description_version, :description_diff]
end
......
......@@ -526,7 +526,7 @@ module EE
end
def iteration_cadences_feature_flag_enabled?
::Feature.enabled?(:iteration_cadences, self, default_enabled: :yaml)
feature_flag_enabled_for_self_or_ancestor?(:iteration_cadences)
end
def user_cap_reached?(use_cache: false)
......
......@@ -320,6 +320,11 @@ RSpec.describe Banzai::Filter::References::IterationReferenceFilter do
markdown = "#{iteration_reference} #{iteration2_reference} #{iteration3_reference}"
max_count += 1
# Feature flag check for iteration_cadences fetches the root ancestor for a group
# so we need to add another query here. This should be removed when the feature flag is removed.
# TODO: https://gitlab.com/gitlab-org/gitlab/-/issues/354878
max_count += 1
expect do
reference_filter(markdown, { project: nil, group: group2 })
end.not_to exceed_all_query_limit(max_count)
......
......@@ -2167,6 +2167,13 @@ RSpec.describe Group do
end
end
describe '#iteration_cadences_feature_flag_enabled?' do
it_behaves_like 'checks self and root ancestor feature flag' do
let(:feature_flag) { :iteration_cadences }
let(:feature_flag_method) { :iteration_cadences_feature_flag_enabled? }
end
end
describe '#user_cap_reached?' do
subject(:user_cap_reached_for_group?) { group.user_cap_reached? }
......
......@@ -31,6 +31,7 @@ module RuboCop
].freeze
SELF_METHODS = %i[
push_frontend_feature_flag
push_force_frontend_feature_flag
limit_feature_flag=
limit_feature_flag_for_override=
].freeze + EXPERIMENT_METHODS + RUGGED_METHODS + WORKER_METHODS
......
......@@ -3366,44 +3366,9 @@ RSpec.describe Group do
end
describe '#work_items_feature_flag_enabled?' do
let_it_be(:root_group) { create(:group) }
let_it_be(:group) { create(:group, parent: root_group) }
let_it_be(:project) { create(:project, group: group) }
subject { group.work_items_feature_flag_enabled? }
context 'when work_items FF is enabled for the root group' do
before do
stub_feature_flags(work_items: root_group)
end
it { is_expected.to be_truthy }
end
context 'when work_items FF is enabled for the group' do
before do
stub_feature_flags(work_items: group)
end
it { is_expected.to be_truthy }
context 'when root_group is the actor' do
it 'is not enabled if the FF is enabled for a child' do
expect(root_group).not_to be_work_items_feature_flag_enabled
end
end
end
context 'when work_items FF is disabled globally' do
before do
stub_feature_flags(work_items: false)
end
it { is_expected.to be_falsey }
end
context 'when work_items FF is enabled globally' do
it { is_expected.to be_truthy }
it_behaves_like 'checks self and root ancestor feature flag' do
let(:feature_flag) { :work_items }
let(:feature_flag_method) { :work_items_feature_flag_enabled? }
end
end
end
# frozen_string_literal: true
RSpec.shared_examples 'checks self and root ancestor feature flag' do
let_it_be(:root_group) { create(:group) }
let_it_be(:group) { create(:group, parent: root_group) }
let_it_be(:project) { create(:project, group: group) }
subject { group.public_send(feature_flag_method) }
context 'when FF is enabled for the root group' do
before do
stub_feature_flags(feature_flag => root_group)
end
it { is_expected.to be_truthy }
end
context 'when FF is enabled for the group' do
before do
stub_feature_flags(feature_flag => group)
end
it { is_expected.to be_truthy }
context 'when root_group is the actor' do
it 'is not enabled if the FF is enabled for a child' do
expect(root_group.public_send(feature_flag_method)).to be_falsey
end
end
end
context 'when FF is disabled globally' do
before do
stub_feature_flags(feature_flag => false)
end
it { is_expected.to be_falsey }
end
context 'when FF is enabled globally' do
it { is_expected.to be_truthy }
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