[Bps-public-commit] rt-extension-changemanagement branch master updated. 91a7a4924cfdeab4268739cf12d81affacc33b85
BPS Git Server
git at git.bestpractical.com
Fri Feb 11 15:18:26 UTC 2022
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "rt-extension-changemanagement".
The branch, master has been updated
via 91a7a4924cfdeab4268739cf12d81affacc33b85 (commit)
via cbcb4ca69bbcd70c3506aa59f44873c9dcc39394 (commit)
via 390ce3e6f9a3b71104020c0f948fd8f81b1bf10f (commit)
via af7c1f9f02c2a8d9970563a568fc50e7d54e0eb4 (commit)
via 7e64be22e802fb8099a8d0e658ebd36dce02cb28 (commit)
via 5747a20124c3db03bf42429b5e2451e2207369db (commit)
via e621f2ce834d310198ac70a97dc576d6738738db (commit)
via 2a9c5024742d518c1ba6a2ee6f9b42412bbf49c2 (commit)
via 8da31dec8afbabfdc43637d2ecaaa695e6fed21f (commit)
via 5fddaad8919e8c2cbbf598467c70facac3795847 (commit)
via da0432800f62f484d04951083a8edc1c6df22c11 (commit)
via cd01df58cc64a0e1885b0d0724248e2b1d287eb9 (commit)
via 95081b3d1a6826f982693785ce83362254007af2 (commit)
via 3f72053b28839de11d6b42f71e710908219c2aef (commit)
from c9987f89c80200fc99ec00bad17968cbdb1b96e6 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit 91a7a4924cfdeab4268739cf12d81affacc33b85
Author: Jason Crome <jcrome at bestpractical.com>
Date: Fri Feb 11 10:18:15 2022 -0500
Finish documentation
diff --git a/lib/RT/Extension/ChangeManagement.pm b/lib/RT/Extension/ChangeManagement.pm
index 97e64f4..74d2fc8 100644
--- a/lib/RT/Extension/ChangeManagement.pm
+++ b/lib/RT/Extension/ChangeManagement.pm
@@ -68,18 +68,19 @@ to create tickets in this queue.
=head2 Custom Roles
-There are two roles than can be assigned to users that are part of the change
-management process:
+Users can be assigned several roles that are part of the change management process:
=over
=item Change Reviewer
-Someone who can approve a change request
+Person who reviews incoming change requests, and is responsible for approving or
+denying a change request. Can be assigned to a group.
=item Change Implementor
-Someone who can implement a change request
+Person who is responsible for implementing a change request. This role can be assigned
+to a group.
=back
@@ -191,11 +192,13 @@ changes in the event that the deployment process is unsuccessful.
Date that the change was started. This is B<not> the same as the normal Started
date on the ticket - Started is set when the ticket is moved to an open status
(such as approved); Change Started is when someone actually started implementation
-of the change.
+of the change. This is set automatically when a change ticket's status changes to
+in progress or partially deployed.
=head3 Change Complete
-Date that the change was successfully deployed (or, partially deployed).
+Date that the change was successfully deployed. This is set automatically when a
+change ticket's status changes to deployed.
=head2 Actions
@@ -231,18 +234,6 @@ Changes the status of the request to failed. Requires the Change Implementor rol
Cancels the change request (changes status to failed). Requires the Change Implementor role.
-=head2 Rights
-
-=head3 Change Reviewer
-
-Person who reviews incoming change requests, and is responsible for approving or
-denying a change request. Can be assigned to a group.
-
-=head3 Change Implementor
-
-Person who is responsible for implementing a change request. This role can be assigned
-to a group.
-
=head1 CUSTOMIZING AND EXTENDING
There are some ways RT::Extension::ChangeManagement can be customized to provide
@@ -282,12 +273,8 @@ could happen if the change goes awry, etc. Text.
Using L<RT::Extension::MandatoryOnTransition>, any of the above fields can be made
required upon a status change. For example, you may wish to make Implementation Steps,
Validation Steps, and Impact Assessment required fields before a change request can
-be approved.
-
-=head3 Calendar View
-
-With L<RTx::Calendar>, you can add a calendar portlet to your dashboard, as well
-as a full page calendar view of change management tickets and reminders.
+be approved. See F<etc/ChangeManagement_Config.pm> for a ready-to-use example with
+the out of the box configuration.
=head3 Default Values for Custom Fields
commit cbcb4ca69bbcd70c3506aa59f44873c9dcc39394
Author: Jason Crome <jcrome at bestpractical.com>
Date: Fri Feb 11 10:17:28 2022 -0500
Create example MandatoryOnTransition configuration
diff --git a/etc/ChangeManagement_Config.pm b/etc/ChangeManagement_Config.pm
index 23af68d..7bd5382 100644
--- a/etc/ChangeManagement_Config.pm
+++ b/etc/ChangeManagement_Config.pm
@@ -114,5 +114,28 @@ Set(%Lifecycles,
}
);
+# Delete the =pod and =cut to activate this configuration.
+# This example illustrates how to make Change Reviewer, Change Implementor,
+# Change Type, Change Category, and Rollback Plan mandatory for approval
+# of a change management ticket. Make sure to enable MandatoryOnTransition in
+# your primary RT configuration by adding the following:
+# Plugin( "RT::Extension::MandatoryOnTransition" );
+
+=pod
+
+Set( %MandatoryOnTransition,
+ 'Change Management' => {
+ 'requested -> approved' => [
+ 'CF.Change Type',
+ 'CF.Change Category',
+ 'CF.Rollback Plan',
+ 'CustomRole.Change Reviewer',
+ 'CustomRole.Change Implementor',
+ ],
+ },
+);
+
+=cut
+
1;
commit 390ce3e6f9a3b71104020c0f948fd8f81b1bf10f
Author: Jason Crome <jcrome at bestpractical.com>
Date: Fri Feb 11 10:16:53 2022 -0500
Create basic Change Management ACLs
diff --git a/etc/initialdata b/etc/initialdata
index f69534b..b01ab94 100644
--- a/etc/initialdata
+++ b/etc/initialdata
@@ -153,6 +153,37 @@ our @Scrips = (
},
);
+# These rights aren't the most useful, but it lets everyone, at minimum,
+# submit a ticket.
+my @EveryoneRights = qw/CreateTicket ReplyToTicket SeeQueue/;
+our @ACL = map {
+ {
+ Right => $_,
+ Queue => 'Change Management',
+ GroupDomain => 'SystemInternal',
+ GroupType => 'Everyone'
+ }
+} @EveryoneRights;
+
+# More useful set of rights. Anyone in these groups can see the entirety of
+# change management tickets, and if a member of one of these groups
+# is assigned to one of the change management roles, they can perform the
+# appropriate actions.
+my @ChangeManagementRights = qw/CommentOnTicket Watch SeeCustomField
+ SeeQueue ShowTicket OwnTicket WatchAsAdminCC StealTicket TakeTicket
+ ShowTicketComments ModifyTicket ModifyCustomField ShowOutgoingEmail
+/;
+foreach my $group( 'Change Management', 'Change Review Team' ) {
+ push @ACL, map {
+ {
+ Right => $_,
+ Queue => 'Change Management',
+ GroupDomain => 'UserDefined',
+ GroupId => $group,
+ }
+ } @ChangeManagementRights;
+}
+
#
# Create some saved searches; these will form the basis of the dashboard below. Add more
# to suit your organization's needs.
commit af7c1f9f02c2a8d9970563a568fc50e7d54e0eb4
Author: Jason Crome <jcrome at bestpractical.com>
Date: Thu Feb 10 15:26:32 2022 -0500
Auto set Change Started/Completed on status change
These dates are important for dashboard reporting and searching, and as
such, the user shouldn't have to think about setting them. Made a custom
action to set the date, and use the StatusChange condition to determine
if they need setting.
diff --git a/etc/initialdata b/etc/initialdata
index 6675f3e..f69534b 100644
--- a/etc/initialdata
+++ b/etc/initialdata
@@ -102,6 +102,57 @@ our @CustomRoles = (
},
);
+our @ScripConditions = (
+ {
+ Name => 'On Change Started',
+ Description => 'When an approved change is started',
+ ExecModule => 'StatusChange',
+ Argument => 'old: approved; new: in progress, partially deployed',
+ ApplicableTransTypes => 'Any'
+ },
+ {
+ Name => 'On Change Completed',
+ Description => 'When an approved change is completed',
+ ExecModule => 'StatusChange',
+ Argument => 'new: deployed',
+ ApplicableTransTypes => 'Any'
+ },
+);
+
+our @ScripActions = (
+ {
+ Name => 'Set Change Started to Today',
+ Description => '',
+ ExecModule => 'SetCustomFieldDate',
+ Argument => 'Change Started'
+ },
+ {
+ Name => 'Set Change Completed to Today',
+ Description => '',
+ ExecModule => 'SetCustomFieldDate',
+ Argument => 'Change Completed'
+ },
+);
+
+our @Scrips = (
+ {
+ Queue => ['Change Management'],
+ Description => 'On Change Started Set Change Started to Today',
+ ScripCondition => 'On Change Started',
+ ScripAction => 'Set Change Started to Today',
+ Template => 'Blank',
+ Stage => 'TransactionCreate',
+ },
+ {
+ Queue => ['Change Management'],
+ Description => 'On Change Completed Set Change Completed to Today',
+ ScripCondition => 'On Change Completed',
+ ScripAction => 'Set Change Completed to Today',
+ Template => 'Blank',
+ Stage => 'TransactionCreate',
+ },
+);
+
#
# Create some saved searches; these will form the basis of the dashboard below. Add more
# to suit your organization's needs.
diff --git a/lib/RT/Action/SetCustomFieldDate.pm b/lib/RT/Action/SetCustomFieldDate.pm
new file mode 100644
index 0000000..ff32095
--- /dev/null
+++ b/lib/RT/Action/SetCustomFieldDate.pm
@@ -0,0 +1,32 @@
+package RT::Action::SetCustomFieldDate;
+use base 'RT::Action';
+
+use strict;
+use warnings;
+
+sub Prepare {
+ # nothing to prepare
+ return 1;
+}
+
+sub Commit {
+ my $self = shift;
+ my $field = $self->Argument;
+
+ RT::Logger->error("Field required") unless $field;
+ return unless $field;
+
+ my $DateObj = RT::Date->new($self->TicketObj->CurrentUser);
+ $DateObj->SetToNow;
+ my $value = $DateObj->ISO(Timezone => 'user');
+
+ my ($ret, $msg) = $self->TicketObj->AddCustomFieldValue(Field => $field, Value => $value);
+ unless ($ret) {
+ RT->Logger->error($msg);
+ }
+ return $ret;
+}
+
+RT::Base->_ImportOverlays();
+
+1;
diff --git a/lib/RT/Extension/ChangeManagement.pm b/lib/RT/Extension/ChangeManagement.pm
index d9f6c6d..97e64f4 100644
--- a/lib/RT/Extension/ChangeManagement.pm
+++ b/lib/RT/Extension/ChangeManagement.pm
@@ -181,15 +181,22 @@ Any change that doesn't fall into the other types.
=back
-=head3 Deployed Date
-
-Date that the change was successfully deployed (or, partially deployed)
-
=head3 Rollback Plan
A description of the steps necessary to perform a rollback of the proposed
changes in the event that the deployment process is unsuccessful.
+=head3 Change Started
+
+Date that the change was started. This is B<not> the same as the normal Started
+date on the ticket - Started is set when the ticket is moved to an open status
+(such as approved); Change Started is when someone actually started implementation
+of the change.
+
+=head3 Change Complete
+
+Date that the change was successfully deployed (or, partially deployed).
+
=head2 Actions
=head3 Submit Request
@@ -277,6 +284,11 @@ required upon a status change. For example, you may wish to make Implementation
Validation Steps, and Impact Assessment required fields before a change request can
be approved.
+=head3 Calendar View
+
+With L<RTx::Calendar>, you can add a calendar portlet to your dashboard, as well
+as a full page calendar view of change management tickets and reminders.
+
=head3 Default Values for Custom Fields
If you look at F<etc/initialdata> in the plugin directory, you will find a section
commit 7e64be22e802fb8099a8d0e658ebd36dce02cb28
Author: Jason Crome <jcrome at bestpractical.com>
Date: Thu Feb 10 15:26:08 2022 -0500
Make action name consistent with others
diff --git a/etc/ChangeManagement_Config.pm b/etc/ChangeManagement_Config.pm
index d0be04a..23af68d 100644
--- a/etc/ChangeManagement_Config.pm
+++ b/etc/ChangeManagement_Config.pm
@@ -61,7 +61,7 @@ Set(%Lifecycles,
label => 'Start Deployment',
},
'approved -> cancelled' => {
- label => 'Cancel Deployment',
+ label => 'Deployment Cancelled',
},
'in progress -> deployed' => {
label => 'Deployment Complete',
commit 5747a20124c3db03bf42429b5e2451e2207369db
Author: Jason Crome <jcrome at bestpractical.com>
Date: Thu Feb 10 11:55:37 2022 -0500
Add action: cancel deployment before start
diff --git a/etc/ChangeManagement_Config.pm b/etc/ChangeManagement_Config.pm
index 9e29f19..d0be04a 100644
--- a/etc/ChangeManagement_Config.pm
+++ b/etc/ChangeManagement_Config.pm
@@ -60,6 +60,9 @@ Set(%Lifecycles,
'approved -> in progress' => {
label => 'Start Deployment',
},
+ 'approved -> cancelled' => {
+ label => 'Cancel Deployment',
+ },
'in progress -> deployed' => {
label => 'Deployment Complete',
},
commit e621f2ce834d310198ac70a97dc576d6738738db
Author: Jason Crome <jcrome at bestpractical.com>
Date: Thu Feb 10 11:52:42 2022 -0500
Reorder/recaption CFs; add Change Started
diff --git a/etc/ChangeManagement_Config.pm b/etc/ChangeManagement_Config.pm
index 5b0dbc6..9e29f19 100644
--- a/etc/ChangeManagement_Config.pm
+++ b/etc/ChangeManagement_Config.pm
@@ -2,7 +2,7 @@
# ticket display
Set(%CustomFieldGroupings,
'RT::Ticket' => [
- 'Dates' => ['Change Completed'],
+ 'Dates' => ['Change Started','Change Completed'],
'Change Management' => [
'Change Category',
'Change Type',
diff --git a/etc/initialdata b/etc/initialdata
index 49df9bc..6675f3e 100644
--- a/etc/initialdata
+++ b/etc/initialdata
@@ -48,23 +48,32 @@ our @CustomFields = (
SortOrder => 2
},
{
- Name => 'Change Completed',
- EntryHint => 'Date when this change the change was completed',
+ Name => 'Rollback Plan',
+ EntryHint => 'Explain the backout plan to restore normal operations',
LookupType => 'RT::Queue-RT::Ticket',
- Type => 'DateTime',
+ Type => 'Text',
ApplyTo => ['Change Management'],
MaxValues => 1,
SortOrder => 3,
},
{
- Name => 'Rollback Plan',
- EntryHint => 'Explain the backout plan to restore normal operations',
+ Name => 'Change Started',
+ EntryHint => 'Date when this change was started',
LookupType => 'RT::Queue-RT::Ticket',
- Type => 'Text',
+ Type => 'DateTime',
ApplyTo => ['Change Management'],
MaxValues => 1,
SortOrder => 4,
},
+ {
+ Name => 'Change Completed',
+ EntryHint => 'Date when this change was completed',
+ LookupType => 'RT::Queue-RT::Ticket',
+ Type => 'DateTime',
+ ApplyTo => ['Change Management'],
+ MaxValues => 1,
+ SortOrder => 5,
+ },
);
our @Groups = (
commit 2a9c5024742d518c1ba6a2ee6f9b42412bbf49c2
Author: Jason Crome <jcrome at bestpractical.com>
Date: Thu Feb 10 11:46:32 2022 -0500
Show more info on the change mgmt dashboard
Made the dashboard take the full page width, and showed a lot of
additional details to see what changes need doing and have been done at
a glance.
diff --git a/etc/initialdata b/etc/initialdata
index 33f7854..49df9bc 100644
--- a/etc/initialdata
+++ b/etc/initialdata
@@ -68,6 +68,10 @@ our @CustomFields = (
);
our @Groups = (
+ {
+ Name => 'Change Management',
+ Description => 'People who can create change management tickets and work in change management lifecycle',
+ },
{
Name => 'Change Review Team',
Description => 'People responsible for approving change requests',
@@ -99,8 +103,8 @@ our @Attributes = (
Content =>
{ Format => q{'<a href="__WebPath__/Ticket/Display.html?id=__id__">__id__</a>/TITLE:#',}
. q{'<a href="__WebPath__/Ticket/Display.html?id=__id__">__Subject__</a>/TITLE:Subject',}
- . q{Due,'CF.{Change Type}', 'CF.{Change Category}'},
- Query => 'Queue = \'Change Management\' AND Status = \'approved\' AND \'due\' <= \'7 days\'',
+ . q{Due,'CF.{Change Type}', 'CF.{Change Category}',Priority,'CustomRole.{Change Reviewer}.Name','CustomRole.{Change Implementor}.Name','CF.{Change Started}'},
+ Query => 'Queue = \'Change Management\' AND ( Status = \'approved\' OR Status = \'in progress\' OR Status = \'partially deployed\' ) AND \'due\' <= \'7 days\'',
OrderBy => 'due ASC',
},
},
@@ -109,7 +113,7 @@ our @Attributes = (
Content =>
{ Format => q{'<a href="__WebPath__/Ticket/Display.html?id=__id__">__id__</a>/TITLE:#',}
. q{'<a href="__WebPath__/Ticket/Display.html?id=__id__">__Subject__</a>/TITLE:Subject',}
- . q{'CF.{Change Completed}','CF.{Change Type}', 'CF.{Change Category}'},
+ . q{'CF.{Change Type}', 'CF.{Change Category}',Priority,'CustomRole.{Change Reviewer}.Name','CustomRole.{Change Implementor}.Name','CF.{Change Completed}',},
Query => 'Queue = \'Change Management\' AND Status = \'deployed\' AND \'CF.{Change Completed}\' >= \'30 days ago\'',
OrderBy => 'due ASC',
},
@@ -177,32 +181,6 @@ our @Final = sub {
body => [
@searches,
],
- sidebar => [
- { pane => 'body',
- portlet_type => 'component',
- component => 'QuickCreate',
- description => 'QuickCreate',
- path => '/Elements/QuickCreate',
- },
- { pane => 'sidebar',
- portlet_type => 'component',
- component => 'MyReminders',
- description => 'MyReminders',
- path => '/Elements/MyReminders',
- },
- { pane => 'sidebar',
- portlet_type => 'component',
- component => 'Dashboards',
- description => 'Dashboards',
- path => '/Elements/Dashboards',
- },
- { pane => 'sidebar',
- portlet_type => 'component',
- component => 'RefreshHomepage',
- description => 'RefreshHomepage',
- path => '/Elements/RefreshHomepage',
- },
- ]
};
# fill content
commit 8da31dec8afbabfdc43637d2ecaaa695e6fed21f
Author: Jason Crome <jcrome at bestpractical.com>
Date: Mon Feb 7 17:28:10 2022 -0500
Add saved searches, change management dashboard
Items aren't going to show up as completed in the last 30 days unless
the Change Completed date is filled in, so we need to create a scrip to
fill that in automatically when deployment completes.
diff --git a/etc/initialdata b/etc/initialdata
index 22cf40e..33f7854 100644
--- a/etc/initialdata
+++ b/etc/initialdata
@@ -89,17 +89,44 @@ our @CustomRoles = (
},
);
+#
+# Create some saved searches; these will form the basis of the dashboard below. Add more
+# to suit your organization's needs.
#
-# This is an example of how to make a custom field have a default value.
-# As most changes will be Standard, it makes sense to use it as the default.
-# You can similarly make other custom fields defined above have default values
-# by providing the name of the custom field to Load (like Change Type is below)
-# and changing Values to be the default value of the field (similar to how Standard
-# is set below).
-#
-# Remember that the custom field name and default values are case sensitive!
-#
+our @Attributes = (
+ { Name => 'Search - Changes Scheduled, Next 7 Days',
+ Description => 'Change management requests due in the next 7 days', # loc
+ Content =>
+ { Format => q{'<a href="__WebPath__/Ticket/Display.html?id=__id__">__id__</a>/TITLE:#',}
+ . q{'<a href="__WebPath__/Ticket/Display.html?id=__id__">__Subject__</a>/TITLE:Subject',}
+ . q{Due,'CF.{Change Type}', 'CF.{Change Category}'},
+ Query => 'Queue = \'Change Management\' AND Status = \'approved\' AND \'due\' <= \'7 days\'',
+ OrderBy => 'due ASC',
+ },
+ },
+ { Name => 'Search - Changes Deployed, Last 30 Days',
+ Description => 'Change management requests completed in the last 30 days', # loc
+ Content =>
+ { Format => q{'<a href="__WebPath__/Ticket/Display.html?id=__id__">__id__</a>/TITLE:#',}
+ . q{'<a href="__WebPath__/Ticket/Display.html?id=__id__">__Subject__</a>/TITLE:Subject',}
+ . q{'CF.{Change Completed}','CF.{Change Type}', 'CF.{Change Category}'},
+ Query => 'Queue = \'Change Management\' AND Status = \'deployed\' AND \'CF.{Change Completed}\' >= \'30 days ago\'',
+ OrderBy => 'due ASC',
+ },
+ },
+);
+
our @Final = sub {
+ #
+ # This is an example of how to make a custom field have a default value.
+ # As most changes will be Standard, it makes sense to use it as the default.
+ # You can similarly make other custom fields defined above have default values
+ # by providing the name of the custom field to Load (like Change Type is below)
+ # and changing Values to be the default value of the field (similar to how Standard
+ # is set below).
+ #
+ # Remember that the custom field name and default values are case sensitive!
+ #
my $queue_obj = RT::Queue->new(RT->SystemUser);
my $queue = 'Change Management';
$queue_obj->Load($queue);
@@ -118,4 +145,73 @@ our @Final = sub {
} else {
die "Could not set default for: ".$cf->Name;
}
+
+ # Create a change management dashboard.
+ # Combine this with the Calendar extension for an even more informative dashboard experience!
+ my $dashboard = RT::Dashboard->new( RT->SystemUser );
+ ( $ret, $msg ) = $dashboard->Save(
+ Name => 'Change Management',
+ Privacy => join( '-', ref( RT->System ), RT->System->Id ),
+ );
+
+ if ($ret) {
+ my @searches;
+ for my $search_name ( 'Changes Scheduled, Next 7 Days', 'Changes Deployed, Last 30 Days' ) {
+ my ($search) = RT::System->new( RT->SystemUser )->Attributes->Named( 'Search - ' . $search_name );
+ if ($search) {
+ push @searches,
+ {
+ pane => 'body',
+ portlet_type => 'search',
+ id => $search->Id,
+ description => "Saved Search: $search_name",
+ privacy => join( '-', ref( RT->System ), RT->System->Id ),
+ };
+ }
+ else {
+ RT->Logger->error("Couldn't find search $search_name");
+ }
+ }
+
+ my $panes = {
+ body => [
+ @searches,
+ ],
+ sidebar => [
+ { pane => 'body',
+ portlet_type => 'component',
+ component => 'QuickCreate',
+ description => 'QuickCreate',
+ path => '/Elements/QuickCreate',
+ },
+ { pane => 'sidebar',
+ portlet_type => 'component',
+ component => 'MyReminders',
+ description => 'MyReminders',
+ path => '/Elements/MyReminders',
+ },
+ { pane => 'sidebar',
+ portlet_type => 'component',
+ component => 'Dashboards',
+ description => 'Dashboards',
+ path => '/Elements/Dashboards',
+ },
+ { pane => 'sidebar',
+ portlet_type => 'component',
+ component => 'RefreshHomepage',
+ description => 'RefreshHomepage',
+ path => '/Elements/RefreshHomepage',
+ },
+ ]
+ };
+
+ # fill content
+ my ( $ret, $msg ) = $dashboard->Update( Panes => $panes );
+ if ( !$ret ) {
+ RT->Logger->error("Couldn't update content for dashboard Change Management: $msg");
+ }
+ }
+ else {
+ RT->Logger->error("Couldn't create dashboard Change Management: $msg");
+ }
};
commit 5fddaad8919e8c2cbbf598467c70facac3795847
Author: Jason Crome <jcrome at bestpractical.com>
Date: Thu Feb 3 16:34:35 2022 -0800
Clean up action names; set sample default value
Some action names needed to be renamed for clarity. Set a default value
for change type (most changes are standard changes), and documented how
users can configure their own default values.
diff --git a/etc/initialdata b/etc/initialdata
index 7a2eb48..22cf40e 100644
--- a/etc/initialdata
+++ b/etc/initialdata
@@ -89,3 +89,33 @@ our @CustomRoles = (
},
);
+#
+# This is an example of how to make a custom field have a default value.
+# As most changes will be Standard, it makes sense to use it as the default.
+# You can similarly make other custom fields defined above have default values
+# by providing the name of the custom field to Load (like Change Type is below)
+# and changing Values to be the default value of the field (similar to how Standard
+# is set below).
+#
+# Remember that the custom field name and default values are case sensitive!
+#
+our @Final = sub {
+ my $queue_obj = RT::Queue->new(RT->SystemUser);
+ my $queue = 'Change Management';
+ $queue_obj->Load($queue);
+ die "Failed to load queue $queue" unless $queue_obj->Id;
+
+ my $cf = RT::CustomField->new(RT->SystemUser);
+ my ($ret, $msg) = $cf->Load('Change Type');
+ die $msg unless $ret;
+
+ if ( $cf->id && $cf->SupportDefaultValues ) {
+ ($ret, $msg) = $cf->SetDefaultValues(
+ Object => $queue_obj,
+ Values => 'Standard',
+ );
+ die $msg unless $ret;
+ } else {
+ die "Could not set default for: ".$cf->Name;
+ }
+};
diff --git a/lib/RT/Extension/ChangeManagement.pm b/lib/RT/Extension/ChangeManagement.pm
index 29eda2d..d9f6c6d 100644
--- a/lib/RT/Extension/ChangeManagement.pm
+++ b/lib/RT/Extension/ChangeManagement.pm
@@ -168,7 +168,8 @@ One of the three types of change types outlined in ITIL:
=item Standard
-A low risk, pre-authorized change that follows a repeatable process.
+A low risk, pre-authorized change that follows a repeatable process. This is the
+default for new tickets in the Change Management queue.
=item Emergency
@@ -203,15 +204,15 @@ Mark a change management request ticket as approved. Requires the Change Reviewe
Deny the change management request. Requires the Change Reviewer role.
-=head3 Start Implementation
+=head3 Start Deployment
Changes the ticket status to in progress. Requires the Change Implementor role.
-=head3 Complete Implementation
+=head3 Deployment Complete
Marks the change request as deployed. Requires the Change Implementor role.
-=head3 Partially Complete
+=head3 Partially Deployed
Marks the change request as partially deployed. Requires the Change Implementor role.
@@ -276,6 +277,25 @@ required upon a status change. For example, you may wish to make Implementation
Validation Steps, and Impact Assessment required fields before a change request can
be approved.
+=head3 Default Values for Custom Fields
+
+If you look at F<etc/initialdata> in the plugin directory, you will find a section
+called C<@Final> (unsurprisingly, it is the last section of configuration).
+There you will find some sample code and documentation for setting a default value
+for a custom field.
+
+The process basically boils down to:
+
+=over
+
+=item Load a named queue
+
+=item Load a custom field by name
+
+=item Set the default value for that custom field in that queue
+
+=back
+
=head2 Approvals Queue
If you have an established Change Review Board, your organization is likely dealing
commit da0432800f62f484d04951083a8edc1c6df22c11
Author: Jason Crome <jcrome at bestpractical.com>
Date: Thu Feb 3 13:06:32 2022 -0800
Description changed to entry hints.
This is what I had originally intended them to be, I just used the wrong
configuration option.
diff --git a/etc/initialdata b/etc/initialdata
index fdef6a0..7a2eb48 100644
--- a/etc/initialdata
+++ b/etc/initialdata
@@ -14,7 +14,7 @@ our @Queues = (
our @CustomFields = (
{
Name => 'Change Category',
- Description => 'High-level categorization of the requested change',
+ EntryHint => 'High-level categorization of the requested change',
Type => 'SelectSingle',
LookupType => 'RT::Queue-RT::Ticket',
ApplyTo => ['Change Management'],
@@ -34,7 +34,7 @@ our @CustomFields = (
},
{
Name => 'Change Type',
- Description => 'Kind of service change being requested',
+ EntryHint => 'Kind of service change being requested',
LookupType => 'RT::Queue-RT::Ticket',
Type => 'SelectSingle',
ApplyTo => ['Change Management'],
@@ -48,8 +48,8 @@ our @CustomFields = (
SortOrder => 2
},
{
- Name => 'Deployed Date',
- Description => 'Date the change was deployed',
+ Name => 'Change Completed',
+ EntryHint => 'Date when this change the change was completed',
LookupType => 'RT::Queue-RT::Ticket',
Type => 'DateTime',
ApplyTo => ['Change Management'],
@@ -58,7 +58,7 @@ our @CustomFields = (
},
{
Name => 'Rollback Plan',
- Description => 'Explain the backout plan to restore normal operations',
+ EntryHint => 'Explain the backout plan to restore normal operations',
LookupType => 'RT::Queue-RT::Ticket',
Type => 'Text',
ApplyTo => ['Change Management'],
commit cd01df58cc64a0e1885b0d0724248e2b1d287eb9
Author: Jason Crome <jcrome at bestpractical.com>
Date: Thu Feb 3 13:00:48 2022 -0800
Renamed actions & CFs, require updates for actions
Action names better reflect the change and not the ticket. Some actions
now require an update - for example, rejecting a change request - the
reviewer should have to tell the requestor *why* the change was
rejected.
Partially Deployed now has some actions as it is not necessarily an end
state. It could be the end, it could be marked failed, etc.
diff --git a/etc/ChangeManagement_Config.pm b/etc/ChangeManagement_Config.pm
index f8f7d54..5b0dbc6 100644
--- a/etc/ChangeManagement_Config.pm
+++ b/etc/ChangeManagement_Config.pm
@@ -2,7 +2,7 @@
# ticket display
Set(%CustomFieldGroupings,
'RT::Ticket' => [
- 'Dates' => ['Deployed Date'],
+ 'Dates' => ['Change Completed'],
'Change Management' => [
'Change Category',
'Change Type',
@@ -51,21 +51,40 @@ Set(%Lifecycles,
},
'requested -> rejected' => {
label => 'Deny Request',
+ update => 'Respond',
+ },
+ 'requested -> cancelled' => {
+ label => 'Deployment Cancelled',
+ update => 'Respond',
},
'approved -> in progress' => {
- label => 'Start Implementation',
+ label => 'Start Deployment',
},
'in progress -> deployed' => {
- label => 'Complete Implementation',
+ label => 'Deployment Complete',
},
'in progress -> partially deployed' => {
- label => 'Partially Complete',
+ label => 'Partially Deployed',
+ update => 'Respond',
},
'in progress -> failed' => {
label => 'Deployment Failed',
+ update => 'Respond',
},
'in progress -> cancelled' => {
label => 'Deployment Cancelled',
+ update => 'Respond',
+ },
+ 'partially deployed -> deployed' => {
+ label => 'Deployment Complete',
+ },
+ 'partially deployed -> failed' => {
+ label => 'Deployment Failed',
+ update => 'Respond',
+ },
+ 'partially deployed -> cancelled' => {
+ label => 'Deployment Cancelled',
+ update => 'Respond',
},
]
},
commit 95081b3d1a6826f982693785ce83362254007af2
Author: Jason Crome <jcrome at bestpractical.com>
Date: Thu Feb 3 12:02:36 2022 -0800
Combine config files, remove old lifecycle config
diff --git a/etc/ChangeManagement_Config.pm b/etc/ChangeManagement_Config.pm
index 06bfe15..f8f7d54 100644
--- a/etc/ChangeManagement_Config.pm
+++ b/etc/ChangeManagement_Config.pm
@@ -1,3 +1,5 @@
+# Groups the change management fields together in their own section on the
+# ticket display
Set(%CustomFieldGroupings,
'RT::Ticket' => [
'Dates' => ['Deployed Date'],
@@ -8,3 +10,87 @@ Set(%CustomFieldGroupings,
],
],
);
+
+# Creates the change management lifecycle. Allowed status changes, menu actions,
+# rights, ACLs are defined here. If you're going to make customizations to this
+# extension, most of that work will happen here.
+Set(%Lifecycles,
+ 'Change Management' => {
+ initial => [ qw( requested ) ], # loc_qw
+ active => [ 'approved', 'in progress', 'partially deployed' ], # loc_qw
+ inactive => [ qw( deployed failed cancelled rejected deleted ) ], # loc_qw
+ defaults => {
+ on_create => 'requested',
+ },
+ transitions => {
+ # The following transition is required for ticket creation
+ '' => [ qw( requested ) ],
+ requested => [ qw( approved deployed failed cancelled rejected deleted ), 'in progress', 'partially deployed' ],
+ approved => [ qw( deployed failed cancelled rejected deleted ), 'in progress', 'partially deployed' ],
+ 'in progress' => [ qw( approved deployed failed cancelled rejected deleted ), 'partially deployed' ],
+ 'partially deployed' => [ qw( approved deployed failed cancelled rejected deleted ), 'in progress' ],
+ deployed => [ qw( approved failed cancelled rejected deleted ), 'in progress', 'partially deployed' ],
+ failed => [ qw( approved deployed cancelled rejected deleted ), 'in progress', 'partially deployed' ],
+ cancelled => [ qw( approved deployed failed rejected deleted ), 'in progress', 'partially deployed' ],
+ rejected => [ qw( approved deployed failed cancelled deleted ), 'in progress', 'partially deployed' ],
+ },
+ rights => {
+ 'requested -> approved' => 'Change Reviewer',
+ 'requested -> rejected' => 'Change Reviewer',
+ 'approved -> in progress' => 'Change Implementor',
+ 'in progress -> deployed' => 'Change Implementor',
+ 'in progress -> partially deployed' => 'Change Implementor',
+ 'in progress -> failed' => 'Change Implementor',
+ },
+ actions => [
+ '* -> requested' => {
+ label => 'Submit Request',
+ },
+ 'requested -> approved' => {
+ label => 'Approve Request',
+ },
+ 'requested -> rejected' => {
+ label => 'Deny Request',
+ },
+ 'approved -> in progress' => {
+ label => 'Start Implementation',
+ },
+ 'in progress -> deployed' => {
+ label => 'Complete Implementation',
+ },
+ 'in progress -> partially deployed' => {
+ label => 'Partially Complete',
+ },
+ 'in progress -> failed' => {
+ label => 'Deployment Failed',
+ },
+ 'in progress -> cancelled' => {
+ label => 'Deployment Cancelled',
+ },
+ ]
+ },
+ __maps__ => {
+ 'default -> Change Management' => {
+ 'new' => 'requested',
+ 'resolved' => 'deployed',
+ 'open' => 'in progress',
+ 'rejected' => 'rejected',
+ 'open' => 'partially deployed',
+ 'deleted' => 'deleted',
+ },
+ 'Change Management -> default' => {
+ 'requested' => 'new',
+ 'deployed' => 'resolved',
+ 'rejected' => 'rejected',
+ 'deleted' => 'deleted',
+ 'in progress' => 'open',
+ 'approved' => 'open',
+ 'partially deployed' => 'open',
+ 'failed' => 'resolved',
+ 'cancelled' => 'resolved',
+ },
+ }
+);
+
+1;
+
diff --git a/etc/Lifecycle_config.pm b/etc/Lifecycle_config.pm
deleted file mode 100644
index c1f8578..0000000
--- a/etc/Lifecycle_config.pm
+++ /dev/null
@@ -1,80 +0,0 @@
-Set(%Lifecycles,
- 'Change Management' => {
- initial => [ qw( requested ) ], # loc_qw
- active => [ 'approved', 'in progress', 'partially deployed' ], # loc_qw
- inactive => [ qw( deployed failed cancelled rejected deleted ) ], # loc_qw
- defaults => {
- on_create => 'requested',
- },
- transitions => {
- # The following transition is required for ticket creation
- '' => [ qw( requested ) ],
- requested => [ qw( approved deployed failed cancelled rejected deleted ), 'in progress', 'partially deployed' ],
- approved => [ qw( deployed failed cancelled rejected deleted ), 'in progress', 'partially deployed' ],
- 'in progress' => [ qw( approved deployed failed cancelled rejected deleted ), 'partially deployed' ],
- 'partially deployed' => [ qw( approved deployed failed cancelled rejected deleted ), 'in progress' ],
- deployed => [ qw( approved failed cancelled rejected deleted ), 'in progress', 'partially deployed' ],
- failed => [ qw( approved deployed cancelled rejected deleted ), 'in progress', 'partially deployed' ],
- cancelled => [ qw( approved deployed failed rejected deleted ), 'in progress', 'partially deployed' ],
- rejected => [ qw( approved deployed failed cancelled deleted ), 'in progress', 'partially deployed' ],
- },
- rights => {
- 'requested -> approved' => 'Change Reviewer',
- 'requested -> rejected' => 'Change Reviewer',
- 'approved -> in progress' => 'Change Implementor',
- 'in progress -> deployed' => 'Change Implementor',
- 'in progress -> partially deployed' => 'Change Implementor',
- 'in progress -> failed' => 'Change Implementor',
- },
- actions => [
- '* -> requested' => {
- label => 'Submit Request',
- },
- 'requested -> approved' => {
- label => 'Approve Request',
- },
- 'requested -> rejected' => {
- label => 'Deny Request',
- },
- 'approved -> in progress' => {
- label => 'Start Implementation',
- },
- 'in progress -> deployed' => {
- label => 'Complete Implementation',
- },
- 'in progress -> partially deployed' => {
- label => 'Partially Complete',
- },
- 'in progress -> failed' => {
- label => 'Deployment Failed',
- },
- 'in progress -> cancelled' => {
- label => 'Deployment Cancelled',
- },
- ]
- },
- __maps__ => {
- 'default -> Change Management' => {
- 'new' => 'requested',
- 'resolved' => 'deployed',
- 'open' => 'in progress',
- 'rejected' => 'rejected',
- 'open' => 'partially deployed',
- 'deleted' => 'deleted',
- },
- 'Change Management -> default' => {
- 'requested' => 'new',
- 'deployed' => 'resolved',
- 'rejected' => 'rejected',
- 'deleted' => 'deleted',
- 'in progress' => 'open',
- 'approved' => 'open',
- 'partially deployed' => 'open',
- 'failed' => 'resolved',
- 'cancelled' => 'resolved',
- },
- }
-);
-
-1;
-
commit 3f72053b28839de11d6b42f71e710908219c2aef
Author: Jason Crome <jcrome at bestpractical.com>
Date: Thu Feb 3 12:00:11 2022 -0800
Fix POD errors
The missing initdb section is, as far as I am concerned, a bug, and
therefore lumping it in with this commit.
diff --git a/lib/RT/Extension/ChangeManagement.pm b/lib/RT/Extension/ChangeManagement.pm
index 26d7cce..29eda2d 100644
--- a/lib/RT/Extension/ChangeManagement.pm
+++ b/lib/RT/Extension/ChangeManagement.pm
@@ -24,12 +24,17 @@ Works with RT 5.
May need root permissions
-=item Edit your F</opt/rt4/etc/RT_SiteConfig.pm>
+=item Edit your F</opt/rt5/etc/RT_SiteConfig.pm>
Add this line:
Plugin('RT::Extension::ChangeManagement');
+=item C<make initdb>
+
+Only run this the first time you install this module. If you run this twice,
+you may end up with duplicate data in your database.
+
=item Clear your mason cache
rm -rf /opt/rt5/var/mason_data/obj
@@ -55,7 +60,7 @@ can transform into a fully-featured change management system.
=head2 Change Management Queue
-After installing, you'll see a new queue called L<Change Management> for tracking
+After installing, you'll see a new queue called B<Change Management> for tracking
all of the incoming change requests. You can change the name to anything you like
after installing. In a typical configuration, you will also want to assign an RT
email address, like changes at example.com or crb at example.com (Change Review Team)
@@ -129,8 +134,6 @@ comment on the ticket.
=back
-=head2 Change Management Lifecycle
-
=head2 Custom Fields
=head3 Change Category
-----------------------------------------------------------------------
Summary of changes:
etc/ChangeManagement_Config.pm | 133 +++++++++++++++++++++-
etc/Lifecycle_config.pm | 80 -------------
etc/initialdata | 211 +++++++++++++++++++++++++++++++++--
lib/RT/Action/SetCustomFieldDate.pm | 32 ++++++
lib/RT/Extension/ChangeManagement.pm | 80 ++++++++-----
5 files changed, 418 insertions(+), 118 deletions(-)
delete mode 100644 etc/Lifecycle_config.pm
create mode 100644 lib/RT/Action/SetCustomFieldDate.pm
hooks/post-receive
--
rt-extension-changemanagement
More information about the Bps-public-commit
mailing list