Commit 90c67a4c authored by Max Woolf's avatar Max Woolf

Merge branch '290039-clean-up-epic-boards-feature-flag' into 'master'

Clean up :epic_boards feature flag

See merge request gitlab-org/gitlab!64761
parents 09d4ec74 f32c0491
...@@ -12,10 +12,8 @@ import BoardColumnDeprecated from './board_column_deprecated.vue'; ...@@ -12,10 +12,8 @@ import BoardColumnDeprecated from './board_column_deprecated.vue';
export default { export default {
components: { components: {
BoardAddNewColumn, BoardAddNewColumn,
BoardColumn: BoardColumn,
gon.features?.graphqlBoardLists || gon.features?.epicBoards BoardColumnDeprecated,
? BoardColumn
: BoardColumnDeprecated,
BoardContentSidebar: () => import('~/boards/components/board_content_sidebar.vue'), BoardContentSidebar: () => import('~/boards/components/board_content_sidebar.vue'),
EpicBoardContentSidebar: () => EpicBoardContentSidebar: () =>
import('ee_component/boards/components/epic_board_content_sidebar.vue'), import('ee_component/boards/components/epic_board_content_sidebar.vue'),
...@@ -38,11 +36,14 @@ export default { ...@@ -38,11 +36,14 @@ export default {
computed: { computed: {
...mapState(['boardLists', 'error', 'addColumnForm']), ...mapState(['boardLists', 'error', 'addColumnForm']),
...mapGetters(['isSwimlanesOn', 'isEpicBoard']), ...mapGetters(['isSwimlanesOn', 'isEpicBoard']),
useNewBoardColumnComponent() {
return this.glFeatures.graphqlBoardLists || this.isSwimlanesOn || this.isEpicBoard;
},
addColumnFormVisible() { addColumnFormVisible() {
return this.addColumnForm?.visible; return this.addColumnForm?.visible;
}, },
boardListsToUse() { boardListsToUse() {
return this.glFeatures.graphqlBoardLists || this.isSwimlanesOn || this.isEpicBoard return this.useNewBoardColumnComponent
? sortBy([...Object.values(this.boardLists)], 'position') ? sortBy([...Object.values(this.boardLists)], 'position')
: this.lists; : this.lists;
}, },
...@@ -65,6 +66,9 @@ export default { ...@@ -65,6 +66,9 @@ export default {
return this.canDragColumns ? options : {}; return this.canDragColumns ? options : {};
}, },
boardColumnComponent() {
return this.useNewBoardColumnComponent ? BoardColumn : BoardColumnDeprecated;
},
}, },
methods: { methods: {
...mapActions(['moveList', 'unsetError']), ...mapActions(['moveList', 'unsetError']),
...@@ -102,7 +106,8 @@ export default { ...@@ -102,7 +106,8 @@ export default {
class="boards-list gl-w-full gl-py-5 gl-px-3 gl-white-space-nowrap" class="boards-list gl-w-full gl-py-5 gl-px-3 gl-white-space-nowrap"
@end="handleDragOnEnd" @end="handleDragOnEnd"
> >
<board-column <component
:is="boardColumnComponent"
v-for="(list, index) in boardListsToUse" v-for="(list, index) in boardListsToUse"
:key="index" :key="index"
ref="board" ref="board"
......
...@@ -7,17 +7,16 @@ info: To determine the technical writer assigned to the Stage/Group associated w ...@@ -7,17 +7,16 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# Epic Boards **(PREMIUM)** # Epic Boards **(PREMIUM)**
> - [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/5067) in GitLab 13.10. > - [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/5067) in GitLab 13.10.
> - [Deployed behind a feature flag](../../feature_flags.md), disabled by default. > - [Feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/issues/290039) in GitLab 14.1.
> - [Enabled by default](https://gitlab.com/gitlab-org/gitlab/-/issues/290039) in GitLab 14.0.
> - Enabled on GitLab.com.
> - Recommended for production use.
> - For GitLab self-managed instances, GitLab administrators can opt to [disable it](../../../administration/feature_flags.md).
Epic boards build on the existing [epic tracking functionality](index.md) and Epic boards build on the existing [epic tracking functionality](index.md) and
[labels](../../project/labels.md). Your epics appear as cards in vertical lists, organized by their assigned [labels](../../project/labels.md). Your epics appear as cards in vertical lists, organized by their assigned
labels. labels.
To view an epic board, in a group, select **Epics > Boards**. To view an epic board:
1. On the top bar, select **Menu > Groups** and find your group.
1. On the left sidebar, select **Epics > Boards**.
![GitLab epic board - Premium](img/epic_board_v14_0.png) ![GitLab epic board - Premium](img/epic_board_v14_0.png)
...@@ -29,7 +28,8 @@ Prerequisites: ...@@ -29,7 +28,8 @@ Prerequisites:
To create a new epic board: To create a new epic board:
1. Go to your group and select **Epics > Boards**. 1. On the top bar, select **Menu > Groups** and find your group.
1. On the left sidebar, select **Epics > Boards**.
1. In the upper left corner, select the dropdown with the current board name. 1. In the upper left corner, select the dropdown with the current board name.
1. Select **Create new board**. 1. Select **Create new board**.
1. Enter the new board's title. 1. Enter the new board's title.
...@@ -77,7 +77,8 @@ Prerequisites: ...@@ -77,7 +77,8 @@ Prerequisites:
To create a new list: To create a new list:
1. Go to your group and select **Epics > Boards**. 1. On the top bar, select **Menu > Groups** and find your group.
1. On the left sidebar, select **Epics > Boards**.
1. In the upper-right corner, select **Create list**. 1. In the upper-right corner, select **Create list**.
1. In the **New list** column expand the **Select a label** dropdown and select the label to use as 1. In the **New list** column expand the **Select a label** dropdown and select the label to use as
list scope. list scope.
...@@ -161,22 +162,3 @@ To edit the scope of an epic board: ...@@ -161,22 +162,3 @@ To edit the scope of an epic board:
- Show or hide the Open and Closed columns. - Show or hide the Open and Closed columns.
- Select other labels as the board's scope. - Select other labels as the board's scope.
1. Select **Save changes**. 1. Select **Save changes**.
## Enable or disable epic boards
Epic boards are 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 disable it.
To disable it:
```ruby
Feature.disable(:epic_boards)
```
To enable it:
```ruby
Feature.enable(:epic_boards)
```
...@@ -8,9 +8,6 @@ class Groups::EpicBoardsController < Groups::ApplicationController ...@@ -8,9 +8,6 @@ class Groups::EpicBoardsController < Groups::ApplicationController
before_action :redirect_to_recent_board, only: [:index] before_action :redirect_to_recent_board, only: [:index]
before_action :assign_endpoint_vars before_action :assign_endpoint_vars
before_action do
push_frontend_feature_flag(:epic_boards, group, default_enabled: :yaml)
end
track_redis_hll_event :index, :show, name: 'g_project_management_users_viewing_epic_boards' track_redis_hll_event :index, :show, name: 'g_project_management_users_viewing_epic_boards'
...@@ -70,6 +67,6 @@ class Groups::EpicBoardsController < Groups::ApplicationController ...@@ -70,6 +67,6 @@ class Groups::EpicBoardsController < Groups::ApplicationController
end end
def authorize_read_board! def authorize_read_board!
access_denied! unless Feature.enabled?(:epic_boards, group, default_enabled: :yaml) && can?(current_user, :read_epic_board, group) access_denied! unless can?(current_user, :read_epic_board, group)
end end
end end
...@@ -50,10 +50,6 @@ module Mutations ...@@ -50,10 +50,6 @@ module Mutations
board = authorized_find!(id: args[:board_id]) board = authorized_find!(id: args[:board_id])
epic = authorized_find!(id: args[:epic_id]) epic = authorized_find!(id: args[:epic_id])
unless Feature.enabled?(:epic_boards, board.resource_parent, default_enabled: :yaml)
raise Gitlab::Graphql::Errors::ResourceNotAvailable, 'epic_boards feature is disabled'
end
move_epic(board, epic, move_list_arguments(args).merge(board_id: board.id)) move_epic(board, epic, move_list_arguments(args).merge(board_id: board.id))
{ {
......
...@@ -24,10 +24,6 @@ module Mutations ...@@ -24,10 +24,6 @@ module Mutations
def resolve(**args) def resolve(**args)
board = authorized_find!(id: args[:id]) board = authorized_find!(id: args[:id])
unless Feature.enabled?(:epic_boards, board.resource_parent, default_enabled: :yaml)
raise Gitlab::Graphql::Errors::ResourceNotAvailable, 'epic_boards feature is disabled'
end
::Boards::EpicBoards::UpdateService.new(board.resource_parent, current_user, args).execute(board) ::Boards::EpicBoards::UpdateService.new(board.resource_parent, current_user, args).execute(board)
{ {
......
...@@ -16,7 +16,6 @@ module Resolvers ...@@ -16,7 +16,6 @@ module Resolvers
alias_method :group, :object alias_method :group, :object
def resolve(id: nil) def resolve(id: nil)
return unless Feature.enabled?(:epic_boards, group, default_enabled: :yaml)
return unless group.licensed_feature_available?(:epics) return unless group.licensed_feature_available?(:epics)
authorize! authorize!
......
...@@ -8,7 +8,7 @@ module Boards ...@@ -8,7 +8,7 @@ module Boards
override :can_create_board? override :can_create_board?
def can_create_board? def can_create_board?
Feature.enabled?(:epic_boards, parent, default_enabled: :yaml) true
end end
override :parent_board_collection override :parent_board_collection
......
...@@ -7,10 +7,6 @@ module Boards ...@@ -7,10 +7,6 @@ module Boards
override :execute override :execute
def execute(board) def execute(board)
unless Feature.enabled?(:epic_boards, board.group, default_enabled: :yaml)
return ServiceResponse.error(message: 'Epic boards feature is not enabled.')
end
super super
end end
end end
......
...@@ -11,10 +11,6 @@ module Boards ...@@ -11,10 +11,6 @@ module Boards
return ServiceResponse.error(message: 'Epics feature is not available.') return ServiceResponse.error(message: 'Epics feature is not available.')
end end
unless Feature.enabled?(:epic_boards, list.board.group, default_enabled: :yaml)
return ServiceResponse.error(message: 'Epic boards feature is not enabled.')
end
unless can?(current_user, :admin_epic_board_list, list) unless can?(current_user, :admin_epic_board_list, list)
return ServiceResponse.error(message: 'The epic board list that you are attempting to destroy does not '\ return ServiceResponse.error(message: 'The epic board list that you are attempting to destroy does not '\
'exist or you don\'t have permission to perform this action') 'exist or you don\'t have permission to perform this action')
......
...@@ -42,7 +42,7 @@ module Boards ...@@ -42,7 +42,7 @@ module Boards
end end
def available? def available?
group.licensed_feature_available?(:epics) && Feature.enabled?(:epic_boards, parent, default_enabled: :yaml) group.licensed_feature_available?(:epics)
end end
def allowed? def allowed?
......
...@@ -20,10 +20,9 @@ ...@@ -20,10 +20,9 @@
= link_to group_epics_path(group), title: 'List' do = link_to group_epics_path(group), title: 'List' do
%span= _('List') %span= _('List')
- if Feature.enabled?(:epic_boards, group, default_enabled: :yaml) = nav_link(path: ['epic_boards#index', 'epic_boards#show'], html_options: { class: "home" }) do
= nav_link(path: ['epic_boards#index', 'epic_boards#show'], html_options: { class: "home" }) do = link_to group_epic_boards_path(group), title: 'Boards' do
= link_to group_epic_boards_path(group), title: 'Boards' do %span= _('Boards')
%span= _('Boards')
= nav_link(path: 'roadmap#show', html_options: { class: 'home' }) do = nav_link(path: 'roadmap#show', html_options: { class: 'home' }) do
= link_to group_roadmap_path(group), title: 'Roadmap' do = link_to group_roadmap_path(group), title: 'Roadmap' do
......
---
name: epic_boards
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/48893
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/290039
milestone: '13.7'
type: development
group: group::product planning
default_enabled: true
...@@ -80,28 +80,6 @@ RSpec.describe 'Group navbar' do ...@@ -80,28 +80,6 @@ RSpec.describe 'Group navbar' do
end end
context 'when epics are available' do context 'when epics are available' do
before do
stub_licensed_features(epics: true)
stub_feature_flags(epic_boards: false)
insert_after_nav_item(
_('Group information'),
new_nav_item: {
nav_item: _('Epics'),
nav_sub_items: [
_('List'),
_('Roadmap')
]
}
)
visit group_path(group)
end
it_behaves_like 'verified navigation bar'
end
context 'when epics and epic boards are available' do
before do before do
stub_licensed_features(epics: true) stub_licensed_features(epics: true)
......
...@@ -27,10 +27,9 @@ RSpec.describe ::Mutations::Boards::EpicBoards::Create do ...@@ -27,10 +27,9 @@ RSpec.describe ::Mutations::Boards::EpicBoards::Create do
it { is_expected.to have_graphql_fields(:epic_board).at_least } it { is_expected.to have_graphql_fields(:epic_board).at_least }
end end
context 'with epic feature enabled and epic_boards feature flag enabled' do context 'with epic feature enabled' do
before do before do
stub_licensed_features(epics: true) stub_licensed_features(epics: true)
stub_feature_flags(epic_boards: true)
end end
context 'when user does not have permission to create epic board' do context 'when user does not have permission to create epic board' do
...@@ -52,14 +51,6 @@ RSpec.describe ::Mutations::Boards::EpicBoards::Create do ...@@ -52,14 +51,6 @@ RSpec.describe ::Mutations::Boards::EpicBoards::Create do
end end
end end
context 'with epic_boards feature flag disabled' do
before do
stub_feature_flags(epic_boards: false)
end
it_behaves_like 'epic board creation error'
end
context 'with epic feature disabled' do context 'with epic feature disabled' do
before do before do
stub_licensed_features(epics: false) stub_licensed_features(epics: false)
......
...@@ -42,7 +42,6 @@ RSpec.describe ::Mutations::Boards::EpicBoards::EpicMoveList do ...@@ -42,7 +42,6 @@ RSpec.describe ::Mutations::Boards::EpicBoards::EpicMoveList do
describe '#resolve' do describe '#resolve' do
before do before do
stub_licensed_features(epics: true) stub_licensed_features(epics: true)
stub_feature_flags(epic_boards: true)
end end
context 'when user does not have permissions' do context 'when user does not have permissions' do
......
...@@ -27,10 +27,9 @@ RSpec.describe ::Mutations::Boards::EpicBoards::Update do ...@@ -27,10 +27,9 @@ RSpec.describe ::Mutations::Boards::EpicBoards::Update do
it { is_expected.to have_graphql_fields(:epic_board).at_least } it { is_expected.to have_graphql_fields(:epic_board).at_least }
end end
context 'with epic feature enabled and epic_boards feature flag enabled' do context 'with epic feature enabled' do
before do before do
stub_licensed_features(epics: true) stub_licensed_features(epics: true)
stub_feature_flags(epic_boards: true)
end end
context 'when user does not have permission to update epic board' do context 'when user does not have permission to update epic board' do
...@@ -50,14 +49,6 @@ RSpec.describe ::Mutations::Boards::EpicBoards::Update do ...@@ -50,14 +49,6 @@ RSpec.describe ::Mutations::Boards::EpicBoards::Update do
expect(result[:epic_board].hide_backlog_list).to be_truthy expect(result[:epic_board].hide_backlog_list).to be_truthy
end end
end end
context 'with epic_boards feature flag disabled' do
before do
stub_feature_flags(epic_boards: false)
end
it_behaves_like 'epic board update error'
end
end end
describe '#ready?' do describe '#ready?' do
......
...@@ -18,7 +18,6 @@ RSpec.describe Mutations::Boards::Epics::Create do ...@@ -18,7 +18,6 @@ RSpec.describe Mutations::Boards::Epics::Create do
before do before do
stub_licensed_features(epics: true) stub_licensed_features(epics: true)
stub_feature_flags(epic_boards: true)
end end
let(:mutation) { described_class.new(object: nil, context: { current_user: user }, field: nil) } let(:mutation) { described_class.new(object: nil, context: { current_user: user }, field: nil) }
...@@ -108,16 +107,6 @@ RSpec.describe Mutations::Boards::Epics::Create do ...@@ -108,16 +107,6 @@ RSpec.describe Mutations::Boards::Epics::Create do
end end
end end
context 'with epic boards disabled' do
before do
stub_feature_flags(epic_boards: false)
end
it 'returns an error' do
expect(subject[:errors]).to include 'This feature is not available'
end
end
context 'with epics not available' do context 'with epics not available' do
before do before do
stub_licensed_features(epics: false) stub_licensed_features(epics: false)
......
...@@ -46,16 +46,6 @@ RSpec.describe Resolvers::Boards::EpicBoardsResolver do ...@@ -46,16 +46,6 @@ RSpec.describe Resolvers::Boards::EpicBoardsResolver do
.to contain_exactly(epic_board2, epic_board1) .to contain_exactly(epic_board2, epic_board1)
.and be_sorted.asc.by(&:name) .and be_sorted.asc.by(&:name)
end end
context 'when epic_boards flag is disabled' do
before do
stub_feature_flags(epic_boards: false)
end
it 'returns nil' do
expect(result).to be_nil
end
end
end end
end end
end end
......
...@@ -69,18 +69,5 @@ RSpec.describe 'get list of epic boards' do ...@@ -69,18 +69,5 @@ RSpec.describe 'get list of epic boards' do
expect(graphql_data.dig('group', 'epicBoard', 'hideClosedList')).to eq board1.hide_closed_list expect(graphql_data.dig('group', 'epicBoard', 'hideClosedList')).to eq board1.hide_closed_list
end end
end end
context 'when epic_boards flag is disabled' do
before do
stub_feature_flags(epic_boards: false)
end
it 'returns nil epic_boards' do
post_graphql(pagination_query, current_user: current_user)
boards = graphql_data.dig('group', 'epicBoards')
expect(boards).to be_nil
end
end
end end
end end
...@@ -34,24 +34,9 @@ RSpec.describe 'Reposition and move epic between board lists' do ...@@ -34,24 +34,9 @@ RSpec.describe 'Reposition and move epic between board lists' do
subject { post_graphql_mutation(mutation(params), current_user: current_user) } subject { post_graphql_mutation(mutation(params), current_user: current_user) }
context 'when epic_boards are disabled' do context 'when epics are available' do
before do before do
stub_licensed_features(epics: true) stub_licensed_features(epics: true)
stub_feature_flags(epic_boards: false)
group.add_developer(current_user)
end
it 'raises feature not available error' do
subject
expect(graphql_errors).to include(a_hash_including('message' => 'epic_boards feature is disabled'))
end
end
context 'when epic_boards are enabled' do
before do
stub_licensed_features(epics: true)
stub_feature_flags(epic_boards: true)
end end
context 'when user does not have permissions to admin the board' do context 'when user does not have permissions to admin the board' do
......
...@@ -44,7 +44,6 @@ RSpec.describe Mutations::Boards::Epics::Create do ...@@ -44,7 +44,6 @@ RSpec.describe Mutations::Boards::Epics::Create do
before do before do
group.add_reporter(current_user) group.add_reporter(current_user)
stub_licensed_features(epics: true) stub_licensed_features(epics: true)
stub_feature_flags(epic_boards: true)
end end
context 'when all arguments are given' do context 'when all arguments are given' do
......
...@@ -10,24 +10,8 @@ RSpec.describe Boards::EpicBoards::CreateService, services: true do ...@@ -10,24 +10,8 @@ RSpec.describe Boards::EpicBoards::CreateService, services: true do
let_it_be(:user) { create(:user) } let_it_be(:user) { create(:user) }
let(:parent) { create(:group) } let(:parent) { create(:group) }
let(:epic_boards_enabled) { false }
before do
stub_feature_flags(epic_boards: epic_boards_enabled)
end
context 'with epic boards feature not available' do
it 'does not create a board' do
service = described_class.new(parent, user)
expect(service.execute.payload).not_to be_nil
expect { service.execute }.not_to change(parent.epic_boards, :count)
end
end
context 'with epic boards feature available' do
let(:epic_boards_enabled) { true }
context 'create epic board' do
it_behaves_like 'create a board', :epic_boards it_behaves_like 'create a board', :epic_boards
it 'tracks epic board creation' do it 'tracks epic board creation' do
......
...@@ -12,17 +12,4 @@ RSpec.describe Boards::EpicLists::CreateService do ...@@ -12,17 +12,4 @@ RSpec.describe Boards::EpicLists::CreateService do
create(:epic_list, params.merge(epic_board: board)) create(:epic_list, params.merge(epic_board: board))
end end
end end
context 'when epic_boards feature flag is disabled' do
before do
stub_feature_flags(epic_boards: false)
end
it 'returns an error' do
response = described_class.new(parent, nil).execute(board)
expect(response.success?).to eq(false)
expect(response.errors).to include("Epic boards feature is not enabled.")
end
end
end end
...@@ -18,7 +18,6 @@ RSpec.describe Boards::EpicLists::DestroyService do ...@@ -18,7 +18,6 @@ RSpec.describe Boards::EpicLists::DestroyService do
before do before do
stub_licensed_features(epics: true) stub_licensed_features(epics: true)
stub_feature_flags(epic_boards: true)
end end
context 'when user does not have permission' do context 'when user does not have permission' do
...@@ -50,18 +49,5 @@ RSpec.describe Boards::EpicLists::DestroyService do ...@@ -50,18 +49,5 @@ RSpec.describe Boards::EpicLists::DestroyService do
expect(response.errors).to include("Epics feature is not available.") expect(response.errors).to include("Epics feature is not available.")
end end
end end
context 'when epic_boards feature flag is disabled' do
before do
stub_feature_flags(epic_boards: false)
end
it 'returns an error' do
response = described_class.new(parent, nil).execute(list)
expect(response).to be_error
expect(response.errors).to include("Epic boards feature is not enabled.")
end
end
end end
end end
...@@ -76,13 +76,5 @@ RSpec.describe Boards::Epics::CreateService do ...@@ -76,13 +76,5 @@ RSpec.describe Boards::Epics::CreateService do
context 'when epics feature is not available' do context 'when epics feature is not available' do
it_behaves_like 'epic creation error', /does not exist or you don't have permission/ it_behaves_like 'epic creation error', /does not exist or you don't have permission/
end end
context 'when epic boards feature flag is not enabled' do
before do
stub_feature_flags(epic_boards: false)
end
it_behaves_like 'epic creation error', /not available/
end
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