Commit 7f37c03d authored by Alex Pooley's avatar Alex Pooley

Merge branch '356069-deprecate-manual-iteration-management' into 'master'

Deprecate manual iteration creation

See merge request gitlab-org/gitlab!83046
parents 0df91e78 3e9f9a9c
......@@ -1458,7 +1458,7 @@ Input type: `CreateIssueInput`
WARNING:
**Deprecated** in 14.0.
Use iterationCreate.
Manual iteration management is deprecated. Only automatic iteration cadences will be supported in the future.
Input type: `CreateIterationInput`
......@@ -1470,7 +1470,7 @@ Input type: `CreateIterationInput`
| <a id="mutationcreateiterationdescription"></a>`description` | [`String`](#string) | Description of the iteration. |
| <a id="mutationcreateiterationduedate"></a>`dueDate` | [`String`](#string) | End date of the iteration. |
| <a id="mutationcreateiterationgrouppath"></a>`groupPath` | [`ID`](#id) | Full path of the group with which the resource is associated. |
| <a id="mutationcreateiterationiterationscadenceid"></a>`iterationsCadenceId` | [`IterationsCadenceID`](#iterationscadenceid) | Global ID of the iterations cadence to be assigned to newly created iteration. |
| <a id="mutationcreateiterationiterationscadenceid"></a>`iterationsCadenceId` **{warning-solid}** | [`IterationsCadenceID`](#iterationscadenceid) | **Deprecated:** `iterationCadenceId` is deprecated and will be removed in the future. This argument is ignored, because you can't create an iteration in a specific cadence. In the future only automatic iteration cadences will be allowed. Deprecated in 14.10. |
| <a id="mutationcreateiterationprojectpath"></a>`projectPath` | [`ID`](#id) | Full path of the project with which the resource is associated. |
| <a id="mutationcreateiterationstartdate"></a>`startDate` | [`String`](#string) | Start date of the iteration. |
| <a id="mutationcreateiterationtitle"></a>`title` | [`String`](#string) | Title of the iteration. |
......@@ -3213,6 +3213,10 @@ Input type: `IterationCadenceUpdateInput`
### `Mutation.iterationCreate`
WARNING:
**Deprecated** in 14.10.
Manual iteration management is deprecated. Only automatic iteration cadences will be supported in the future.
Input type: `iterationCreateInput`
#### Arguments
......@@ -3223,7 +3227,7 @@ Input type: `iterationCreateInput`
| <a id="mutationiterationcreatedescription"></a>`description` | [`String`](#string) | Description of the iteration. |
| <a id="mutationiterationcreateduedate"></a>`dueDate` | [`String`](#string) | End date of the iteration. |
| <a id="mutationiterationcreategrouppath"></a>`groupPath` | [`ID`](#id) | Full path of the group with which the resource is associated. |
| <a id="mutationiterationcreateiterationscadenceid"></a>`iterationsCadenceId` | [`IterationsCadenceID`](#iterationscadenceid) | Global ID of the iterations cadence to be assigned to newly created iteration. |
| <a id="mutationiterationcreateiterationscadenceid"></a>`iterationsCadenceId` **{warning-solid}** | [`IterationsCadenceID`](#iterationscadenceid) | **Deprecated:** `iterationCadenceId` is deprecated and will be removed in the future. This argument is ignored, because you can't create an iteration in a specific cadence. In the future only automatic iteration cadences will be allowed. Deprecated in 14.10. |
| <a id="mutationiterationcreateprojectpath"></a>`projectPath` | [`ID`](#id) | Full path of the project with which the resource is associated. |
| <a id="mutationiterationcreatestartdate"></a>`startDate` | [`String`](#string) | Start date of the iteration. |
| <a id="mutationiterationcreatetitle"></a>`title` | [`String`](#string) | Title of the iteration. |
......@@ -8,10 +8,12 @@ module EE
ITERATION_DEPRECATION_MESSAGE = 'Manual iteration management is deprecated. Only automatic iteration cadences will be supported in the future'
prepended do
mount_mutation ::Mutations::Iterations::Create,
deprecated: { reason: ITERATION_DEPRECATION_MESSAGE, milestone: '14.10' }
mount_mutation ::Mutations::Iterations::Delete,
deprecated: { reason: ITERATION_DEPRECATION_MESSAGE, milestone: '14.10' }
mount_aliased_mutation 'CreateIteration', ::Mutations::Iterations::Create,
deprecated: { reason: 'Use iterationCreate', milestone: '14.0' }
deprecated: { reason: ITERATION_DEPRECATION_MESSAGE, milestone: '14.0' }
end
end
end
......
......@@ -21,7 +21,6 @@ module EE
mount_mutation ::Mutations::Epics::AddIssue
mount_mutation ::Mutations::GitlabSubscriptions::Activate
mount_mutation ::Mutations::Projects::SetLocked
mount_mutation ::Mutations::Iterations::Create
mount_mutation ::Mutations::Iterations::Update
mount_mutation ::Mutations::Iterations::Cadences::Create
mount_mutation ::Mutations::Iterations::Cadences::Update
......
......@@ -5,6 +5,10 @@ module Mutations
class Create < BaseMutation
graphql_name 'iterationCreate'
CADENCE_ID_DEPRECATION_MESSAGE = '`iterationCadenceId` is deprecated and will be removed in the future.' \
' This argument is ignored, because you can\'t create an iteration in a specific cadence.' \
' In the future only automatic iteration cadences will be allowed'
include Mutations::ResolvesResourceParent
authorize :create_iteration
......@@ -16,9 +20,10 @@ module Mutations
argument :iterations_cadence_id,
::Types::GlobalIDType[::Iterations::Cadence],
loads: ::Types::Iterations::CadenceType,
required: false,
description: 'Global ID of the iterations cadence to be assigned to newly created iteration.'
deprecated: { reason: CADENCE_ID_DEPRECATION_MESSAGE, milestone: '14.10' },
description: 'Global ID of the iteration cadence to be assigned to the new iteration.' \
'Argument is ignored as it was only used behind the `iteration_cadences` feature flag.'
argument :title,
GraphQL::Types::String,
......@@ -59,6 +64,11 @@ module Mutations
private
def validate_arguments!(parent, args)
# Ignoring argument as it's not necessary for the legacy iteration creation feature.
# Iteration will always be created in the first manual cadence for the group and create one
# if it doesn't exist yet.
args.delete(:iterations_cadence_id)
if args.except(:group_path, :project_path).empty?
raise Gitlab::Graphql::Errors::ArgumentError, 'The list of iteration attributes is empty'
end
......@@ -66,15 +76,6 @@ module Mutations
if !parent.iteration_cadences_feature_flag_enabled? && args[:title].blank?
raise Gitlab::Graphql::Errors::ArgumentError, "Title can't be blank"
end
# Currently there is a single iteration cadence per group, so if `iterations_cadence_id` argument is not provided
# we assign iteration to the only cadence in the group(see `Iteration#set_iterations_cadence`).
# Once we introduce cadence CRUD support we need to specify to which iteration cadence a given iteration
# belongs if there are more than once cadence in the group. Eventually `iterations_cadence_id` argument should
# become required and there should be no need for group_path argument for iteration.
if args[:iterations_cadence].blank? && parent.iterations_cadences.count > 1 && parent.iteration_cadences_feature_flag_enabled?
raise Gitlab::Graphql::Errors::ArgumentError, 'Please provide iterations_cadence_id argument to assign iteration to respective cadence'
end
end
end
end
......
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Types::MutationType do
describe 'deprecated mutations' do
describe 'iterationCreate' do
let(:field) { get_field('iterationCreate') }
it { expect(field.deprecation_reason).to eq('Manual iteration management is deprecated. Only automatic iteration cadences will be supported in the future. Deprecated in 14.10.') }
end
describe 'createIteration' do
let(:field) { get_field('createIteration') }
it { expect(field.deprecation_reason).to eq('Manual iteration management is deprecated. Only automatic iteration cadences will be supported in the future. Deprecated in 14.0.') }
end
end
def get_field(name)
described_class.fields[GraphqlHelpers.fieldnamerize(name)]
end
end
......@@ -34,6 +34,50 @@ RSpec.describe 'Creating an Iteration' do
graphql_mutation_response(:create_iteration)
end
shared_examples 'legacy iteration creation request' do
it 'creates a new iteration in the default manual cadence' do
post_graphql_mutation(mutation, current_user: current_user)
iteration_hash = mutation_response['iteration']
aggregate_failures do
expect(iteration_hash['title']).to eq('title')
expect(iteration_hash['iterationCadence']['id']).to eq(cadence.to_global_id.to_s)
end
end
end
shared_examples 'iteration create request' do
context 'when there are several iteration cadences in the group' do
let_it_be(:extra_cadence) { create(:iterations_cadence, group: group) }
context 'when iteration cadence id is not provided' do
it_behaves_like 'legacy iteration creation request'
end
context 'when iteration cadence id is provided' do
before do
attributes[:iterations_cadence_id] = extra_cadence.to_global_id.to_s
end
it_behaves_like 'legacy iteration creation request'
end
end
context 'when there is only one iteration cadence in the group' do
context 'when iteration cadence id is not provided' do
it_behaves_like 'legacy iteration creation request'
end
context 'when iteration cadence id is provided' do
before do
attributes[:iterations_cadence_id] = cadence.to_global_id.to_s
end
it_behaves_like 'legacy iteration creation request'
end
end
end
context 'when the user does not have permission' do
before do
stub_licensed_features(iterations: true)
......@@ -66,81 +110,12 @@ RSpec.describe 'Creating an Iteration' do
stub_licensed_features(iterations: true)
end
context 'when iteration cadence id is not provided' do
context 'and there is only one iteration cadence in the group' do
it 'creates the iteration for a group' do
post_graphql_mutation(mutation, current_user: current_user)
iteration_hash = mutation_response['iteration']
aggregate_failures do
expect(iteration_hash['title']).to eq('title')
expect(iteration_hash['description']).to eq('some description')
expect(iteration_hash['startDate']).to eq(start_date)
expect(iteration_hash['dueDate']).to eq(end_date)
expect(iteration_hash['iterationCadence']['id']).to eq(group.iterations_cadences.first.to_global_id.to_s)
end
end
end
context 'and there are several iteration cadences in the group' do
let_it_be(:extra_cadence) { create(:iterations_cadence, group: group)}
it_behaves_like 'a mutation that returns top-level errors',
errors: ['Please provide iterations_cadence_id argument to assign iteration to respective cadence']
context 'when iteration_cadences FF is disabled' do
before do
stub_feature_flags(iteration_cadences: false)
end
it 'creates a new iteration in the default cadence' do
post_graphql_mutation(mutation, current_user: current_user)
iteration_hash = mutation_response['iteration']
aggregate_failures do
expect(iteration_hash['title']).to eq('title')
expect(iteration_hash['iterationCadence']['id']).to eq(group.iterations_cadences.first.to_global_id.to_s)
end
end
end
end
end
context 'when cadence provided' do
context 'with correct cadence' do
let_it_be(:extra_cadence) { create(:iterations_cadence, group: group)}
before do
attributes.merge!(iterations_cadence_id: extra_cadence.to_global_id.to_s)
end
it 'creates the iteration for the cadence' do
post_graphql_mutation(mutation, current_user: current_user)
iteration_hash = mutation_response['iteration']
aggregate_failures do
expect(iteration_hash['title']).to eq('title')
expect(iteration_hash['description']).to eq('some description')
expect(iteration_hash['startDate']).to eq(start_date)
expect(iteration_hash['dueDate']).to eq(end_date)
expect(iteration_hash['iterationCadence']['id']).to eq(extra_cadence.to_global_id.to_s)
end
end
context 'with iterations_cadences FF disabled' do
before do
stub_feature_flags(iteration_cadences: false)
end
context 'with non-existing cadence and a signle cadence in the group' do
let(:non_existing_cadence_id) { "gid://gitlab/Iterations::Cadence/#{non_existing_record_id}" }
before do
attributes.merge!(iterations_cadence_id: non_existing_cadence_id)
end
it_behaves_like 'a mutation that returns top-level errors' do
let(:match_errors) do
contain_exactly(include("No object found for `iterationsCadenceId: "))
end
end
end
it_behaves_like 'iteration create request'
end
context 'with iterations_cadences FF enabled' do
......@@ -148,6 +123,8 @@ RSpec.describe 'Creating an Iteration' do
stub_feature_flags(iteration_cadences: true)
end
it_behaves_like 'iteration create request'
context 'when title is not given' do
let(:attributes) { { start_date: start_date, due_date: end_date } }
......
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