Source control process recipes for Rational Team Concert
Evan Hughes, IBM Rational
Last updated: November 20, 2012
Build basis: Rational Team Concert 5.0.2
Every team has process. Some teams are content to let their culture dictate how work is done. But others take a more proactive approach, actively discussing, planning, and agreeing on how they should get things done. And once the hard work of consensus has been reached, they want to formalize it.
This article describes how teams can formalize their source control process by using Rational Team Concert’s preconditions. It is intended for users familiar with Jazz source control and using the process editors to configure preconditions.
Table of Contents
- Source Control Operations with Preconditions
- Deliver (client)
- Deliver (server)
- Deliver Phase 2 (server)
- Modify Component (server)
- Save Change Set Links and Comments (server)
- Save Stream (server)
- Recipe: Ensure Co-ops’ changes are reviewed
- Recipe: Only allow Team Leads to add/remove components
- Recipe: Prevent changes to special files
- Recipe: Disallow certain characters in paths
- Recipe: Ensure copyright is present
- Recipe: Gating on work item approvals
- Recipe: Prevent enhancements from entering bug fix stream
Rational Team Concert allows teams to formalize their process by defining process preconditions. Preconditions validate operations, ensuring that their inputs adhere to team-defined standards. When a precondition blocks an operation, the user has the opportunity to correct their input and try again.
This article describes how teams can customize RTC’s source control preconditions. Before we delve into that, however, we need a brief refresher on process in RTC.
For the purposes of this article, project areas and team areas behave the same way, so we’ll refer to them both as process areas.
Process areas provide a way of grouping operations that are performed on streams and components. A process area may define permissions, which allow users with specific roles to perform an operation; and it may specify preconditions which block operations that do not meet a predefined standard.
Permissions behave in the manner most users would expect: a user may run an operation if they have the appropriate permission. Permissions are assigned to roles. In situations where a user has multiple roles with permissions that effect an operation, they may run the operation if one or more of the roles allow it.
Preconditions are more comprehensive than permissions. They inspect an operation’s inputs and block the operation if the input doesn’t meet some standard. For example, RTC provides a precondition that ensures every change set delivered to a stream has a comment or work item associated with it. If a user attempts to deliver a change set without a comment or associated work item the precondition blocks the operation and the user is told to improve the input.
Permissions vs. Preconditions: There’s more than one way to do it
When process authors give a role a permission, the capability is additive: the role gets a capability it potentially didn’t have before. Conversely, when a process author assigns an precondition to a role, they are removing a capability. In other words, a role starts with no permissions and has them added as needed. Preconditions are the opposite: a role starts with all permitted capabilities and has them reduced as needed.
Working with Preconditions in the RTC User Interfaces
When a precondition prevents an operation from running, we say it is blocked. The RTC client for Eclipse and Visual Studio both show blocked operations in a special Team Advisor view.
The left pane shows the reason the last operation was blocked. The right pane shows an explanation of the blockage. Some preconditions provide quick fixes as links at the bottom of the description pane.
When an operation is blocked the Why did this happen? link at the bottom of the description pane can be very useful. It explains which operation was running (#1), the role that the precondition is configured on (#2), and provides a link to the process area that configured the precondition (#3):
In this case, we can see that the “Modify Component” operation was blocked, the precondition is configured for the default role, and the operation was running in the Brown's Projects project area.
The Team Advisor view offers features useful for process authors. If you are trying to configure an precondition and want to verify that it is running but it isn’t blocking the operation, you can switch the view to hierarchical mode and disable the “Show Failures Only” filter (#1):
In this case, two preconditions ran but did not block the operation (#2). A third precondition eventually blocked the operation.
The RTC command-line tool also displays blocked operations, but does so in a raw manner. Callers of the command line can check for an error code of 17 after scm/lscm terminates:
$ lscm status Workspace: (1002) "dbi ws" <-> (1003) "Freelance" Component: (1004) "Fusion exploration" Baseline: (1005) 1 "Initial Baseline" Outgoing: Change sets: (1006) *--@ 260 "Upgrade power plant on DMC-12" - "<No comment>" 10-Ma> Suspended: Change sets: (1007) ---@ "<No comment>" 26-Apr-2012 02:27 PM $ lscm deliver 1006 Process Reports: Name: Deliver Operation Reports: Name: Source Control Operation Name: Deliver Participant Reports: Name: Require Work Items to Match Query The following work items don't match the query: 260 Problem running 'deliver': 'Deliver' failed. Preconditions have not been met: The following work items don't match the query: 260 $ echo $? 17 $
The RTC web interface shows blocked operations in the message area (#1):
Note that the image above has been edited for clarity and size.
Source Control Operations with Preconditions
Source Control operations can be found by opening a process area editor, navigating to the Process Configuration tab (#1), expanding the Team Configuration node (#2), selecting Operation Behaviour and scrolling down to the Source Control node in the hierarchy (#3).
The above image has been edited for clarity and size.
There are five configurable Source Control operations:
Runs: Before delivery of baselines, change sets, or on a component replacement.
Affects: All components in streams owned by the process area.
The Deliver (client) precondition runs on the client before the server is contacted about the delivery. This operation is most appropriate for preconditions that require client state to execute, such as detecting compilation errors, or whether the most recent JUnits have run.
Unlike server-side preconditions, client-side deliver preconditions have two limitations:
- some preconditions are not available on all clients,
- savvy users are able to disable the execution of preconditions.
Process authors should treat client side process as a recommendation to users, rather than a hard restriction.
Unlike server-side preconditions, client-side deliver preconditions may be marked as overridable, which allows users to flow change sets even after a precondition blocks the delivery.
Runs: Before delivery of baselines, change sets, or on a component replacement.
Affects: All components in streams owned by the process area.
The Deliver (server) operation runs on the server before change sets are added or removed from a component.
The operation is run on the set of change sets that are being added to (or removed from) a component, which is computationally less expensive than the subsequent Deliver Phase 2 (server) operation.
Require Workspaces to Be Caught Up Before Delivery
Ensures that the user does not have incoming changes at the time of delivery. Since users may be responsible for only some of the components in a stream, the precondition can be limited to check specific components.
This precondition ensures developers have all of the changes in a stream before delivering to it, in the hope that they will test with the full stream content before delivery. This works best in IDEs where source is built automatically after an accept.
Restrict Change Set Delivery to Components in a Stream
Limit the roles that are allowed to deliver change sets to components in a specific stream. This prevents teams who don’t own a component from delivering changes to it.
When multiple teams are flowing into a single integration stream, it’s useful to limit delivery privileges to the team that owns each component, rather than allowing a free-for-all in which any developer can delivery to any component.
Note: Unlike other preconditions, this one is designed to operate on all roles, so should only be assigned to the Everyone role.
When making components available to roles, remember: any team area inheriting from the process area that defines the role may use that role. For example, consider the team areas Child1 and Child2 that share the parent Root:
If Child1 has a stream that allows access to anyone with Root Role, anyone from Root, Child1, or Child2 may deliver changes to it.
Using C1 Role to limit access prevents anyone outside of the Child1 team area from modifying the stream, since they can’t be assigned the C1 Role.
Require Work Items to Match Query
When delivering change sets, make sure that associated work items match a query.
This precondition verifies that the work items associated with each change set satisfy a work item query. In this context “satisfy” means the work item will appear when the query runs.
The query allows complex validation of a work item’s fields, including custom attributes. This allows process authors considerable flexibility in controlling the work items associated with change sets being delivered to a stream.
Options on the precondition allow the process author to set whether each change set must have at least one matching work item, or whether every work item must match.
Work item queries can only match work items in their process area. The precondition allows the process author to dictate how work items from foreign process areas are handled: either allowed or denied.
Require Work Items and Comments
Verify that change sets have work item links and/or comments. The precondition can be configured to require change sets to have a comment/OSLC link, or a work item.
If a work item is required, the owner and target iteration can be verified. Although it makes sense to constrain the work item owner and iteration in development streams, this is not true of integration streams, since:
- Change sets are often delivered by release engineers, meaning that the owner identity check would block the delivery.
- Change sets may have been delivered to the development stream in previous iterations. The associated work items were likely targeted at those iterations.
Requiring work items and/or comments is basic code hygiene and should be practiced by all teams.
Require Work Item Approval
Verify that change sets linked to a work item have a minimum number of approvals. The approvals are specified by role, and must be complete at the time of delivery.
Work item approvals are useful to teams that require multiple sets of eyes on change sets. The precondition ensures that a minimum number of approvals have been received before the associated change sets may be delivered to a stream.
Note: Users may accidentally link new change sets to work items that already have approvals. To prevent such oversights, the Prevent Linking to Approved Work Items precondition should be enabled.
Deliver Phase 2 (server)
Runs: Before the delivery of baselines and change sets, or on a component replacement.
Affects: All components in streams owned by the process area.
The Phase 2 delivery operation occurs before a deliver, but after the server has calculated the computationally intensive before/after states of each item that will be modified.
Restrict Changes by Item Name
Prevent changes to files, folders, or symbolic links based on their name. The precondition may be scoped to specific components in a stream.
Items can be matched with path globbing operators (* indicating zero or more characters, or ? indicating exactly one character) or Java regular expressions. Depending on the precondition’s configuration, matching items will either be allowed (ie, all items in a change set must match the pattern) or blocked (ie, no items in a change set may match the pattern).
Regular expressions are matched in the manner of a search: the regex will match a substring of the item name. To require the entire name to match, use a caret (^) and dollar sign ($) to anchor the regex to the start and end of the string.
Note that changes to folders and symbolic links are not considered hierarchically – in other words, preventing a change to all items named src will not prevent delivery of a change set modifying a file in the src folder.
Restrict Changes to Items
Limit the roles that are permitted to change specific files. The precondition can either operate in a mode where the changes to the selected files are allowed or denied.
Restricting changes to files is of use to teams that operate under a lock-down mode, preventing changes to portions of their streams at specific times. Process authors can use this to keep plugin dependencies stable by matching MANIFEST.MF files; or limit string changes after a string freeze.
Ensure that files contain a specific string on delivery. Only files with names matching a specific pattern are checked.
On teams where ownership must be asserted within source code, this allows process authors to force every source file to contain a copyright string.
The Text To Insert field allows the process author to provide text for a quick fix. The quick fix is available on files that lack the match string, allowing the user to automatically update the file to include the required text.
Modify Component (server)
Runs: Before a component is renamed, created, or has permissions set in its contents.
Affects: Components owned by the process area.
Ensure Component Names are Unique
Prevent component name collisions within a process area. This precondition ensures that no two components in a process area have the same name.
This is of particular use to distributed teams that create new components relatively often, as it prevents users from inadvertently giving their components duplicate names.
Save Change Set Links and Comments (server)
Runs: Before a change set is assigned a new comment or has a work item link added/removed.
Affects: Change sets in components owned by the process area.
Prevent Links by Approvers
Ensure that change set authors do not approve their own work items.
This precondition prevents a change set from being linked to a work item with an approver that is also the change set author. The “Require Disinterested Approvers” precondition on work item save prevents an approver from being added to a work item already linked to change sets with the same author. These two preconditions should be used in conjunction with each other.
Restrict Associating to Active Change Sets
Stop incomplete change sets from being associated with work items.
This is useful in processes that require approvals, since active change sets may be modified after the approval is granted.
Prevent Linking to Approved Work Items
Make sure that change sets cannot be linked to work items that already have approvals. This prevents users from inadvertently hijacking an approved work item and pushing more change sets into it.
Teams that want to enforce strict process on work items (using Require Work Item Approval, for example) should use this precondition to ensure that all change sets are individually approved before flowing into a stream.
By default, the precondition blocks linking to any work item with approvals, regardless of the approval state. If your process is more nuanced, and you wish to allow change sets to be linked to work items in specific approval states, you can add them via the the Allowed Link States configuration. The following example allows change sets to link to work items with a pending review.
If a project has decided to use the “Approval” review type to indicate that a developer may start working on a work item, then a work item will always have an “Approval” of type “Approved” when a developer tries to associate a change set with it. In that case, the following configuration makes sense:
Restrict Associating to Closed Work Items
Prevent change set links from being added to or removed from closed work items.
Teams with a strict work item life cycle should use this precondition to stop change sets from being associated or dissociated with the work item whose work is complete.
The precondition also offers an amalgam of other features. It can:
- add a comment to the work item when links are added/removed.
- ensure that the project area of the stream contains the user delivering the changes.
Save Stream (server)
Runs: Before changes to a stream are saved and before changes are made to the snapshots that are associated to the stream.
Affects: Streams owned by the process area.
Ensure Snapshot Names are Unique
Added in 5.0.2. Ensure that the snapshots associated with a stream have a unique name. Snapshots cannot be created for the stream, moved to the stream or renamed on the stream if a snapshot with the same name is already associated with the stream.
Restrict Stream Visibility to be set to Public
Added in 4.0.4. Prevent streams that are private to a project area or team area from being changed to being publicly visable.
Prevent Adding Component to Stream When Component and Stream Owners are Different
Added in 4.0.4. Prevent the addition of components to a stream where the owner of the component differs from the owner of the stream.
Prevent Adding User Owned Component
Added in 4.0.4. Prevent the addition of a user owned component to a stream.
Using preconditions (and occasionally permissions) process authors can control source control operations, ensuring that business processes are adhered to and that a level of code hygiene is achieved. The remainder of this article describes common scenarios and some process patterns for implementing them.
Recipe: Ensure Co-ops’ Changes Are Reviewed
Just because someone has joined your team doesn’t mean that you want them delivering changes right away. Most team members require a probationary period to learn your team’s process and technology. Let’s consider the case of a new co-op student joining your team:
- They need read access to the same artifacts other team members can see
- An experienced team member should sign off on all of their work
- Once sign-off is received on their work, they should be able to use standard tooling to deliver their changes so that they gain experience with your team’s delivery process.
It would be possible to create a co-op role that would have the same rights as every other user except for the Deliver change sets permission. Since permissions are additive, you’d need to ensure that the co-op isn’t inadvertently assigned any other roles that gave them delivery rights. In order for the co-op’s changes to make it into the stream, another user would have to deliver their change set, depriving the co-op of the experience of delivery with RTC.
An easier approach is to create a co-op role in the process area that owns the stream, and to give it a Require Work Item Approval precondition. At the same time, another team member should be given a mentor role. The precondition for the co-op would be configured to require one approval from a user with the mentor role.
With the Require Work Item Approval precondition enabled, the co-op is able to perform their duties in the same manner as any other user, but would require an approval from their mentor to deliver.
Recipe: Only Allow Team Leads to add/remove components
In most work flows, components are rarely added to or removed from streams. Since planned component changes rarely occur, it would be beneficial to stop inadvertent changes by regular users. To do that,
- Modify the ‘Everyone’ role to remove the permissions for Source Control / Save Stream (server) / Modify / Stream / Modify the stream components. Edit the other non-privileged roles in the same manner.
- Modify the ‘Component Lead’ role to add the same permissions.
The permissions can be found on the Process Configuration tab of the process editor:
When a user attempts to add a component to a stream owned by the process area they will see:
Recipe: Prevent deliveries to upstream components
Some teams own a handful of components in their stream, the other components are contributed by upstream teams. In this situation, only release engineers should be allowed to deliver to the upstream components. This prevents accidental changes to a component that the team is not responsible for.
Process authors can use the Restrict Change Set Delivery to Components in a Stream precondition to limit who is allowed to deliver to particular components in a particular stream. Delivery rights are then granted to specific roles. The following screen shot shows an example where any team member may modify the Offshore work component, but only release engineers are allowed to modify the upstream Fusion exploration and Flux Capacitor components.
Note that the Offshore work component is accessible to any user with the team-member role, as defined in the root project area. That means a member of another team area with that role would be able to deliver to the component.
Blocked deliveries will look like:
Recipe: Prevent changes to special files
Some files need protection from modification. For example, internationalization files should not be modified after a string freeze. So long as the files have a consistent (and unique) naming convention they can be protected with the Restrict Changes by Item Name precondition.
In the case of Eclipse’s internationalization mechanism, we want to prevent changes to Messages.java and messages.properties files. We can do that by configuring the precondition in the following manner:
Translators require the opposite configuration. When using gettext, translators generate files with a .po suffix. Since translators should only modify .po files, and never anything else, the precondition can be configured in the following manner:
Note that the precondition is configured to allow additions and content changes, which prevents translators from inadvertently deleting translations.
Recipe: Disallow certain characters in paths
The Restrict Changes by Item Name precondition can be used to enforce platform-specific restrictions on items in source control. The precondition can prevent colons from being delivered from Linux that can’t be loaded on Windows, for example.
The best approach in this scenario is to itemize legal characters as part of a regular expression and require the entire resource name to match the regular expression. To allow existing resources with bad names to be fixed the pattern should only match additions and renames.
Attempts to deliver the addition of a file named bad:name are now blocked by process. The Team Advisor view will display:
By allowing renames, the user can deliver a change that renames an illegally named resource to a legal name.
Recipe: Ensure copyright is present
Although most code hygiene should be enforced on the client since the Eclipse and Visual Studio clients have access to compilers and other software not on the server. If there are hard requirements for source code, it should be enforced centrally on the server.
The Required Content precondition blocks delivery unless specific content appears in a file. It can be used to ensure that copyrights appear in source code. The following example shows the precondition configured to ensure that a copyright appears in all Java files.
The above configuration requires users to add the given copyright text in all files ending with .java. It also provides text that can be inserted by a quick fix.
Recipe: Gating on work item approvals
The meaning of work item approvals depends on the team. One approach is to use a work item approval as a short-hand for approval of the associated change sets. In order for that to mean something restrictions must be placed on associating change sets to work items.
If work item approvals are being used for code reviews, users shouldn’t be able to inadvertently piggyback work on previously approved work items. Process authors can prevent approval hijacking with the Prevent Linking to Approved Work Items precondition. As the name implies, the precondition will prevent change sets from being linked to work items that already have approvals.
In projects where a work item in a “closed” state means that all work on it has been completed, it makes sense to prevent change sets from being linked to closed work items. In that case, process authors can use the Restrict Associating to Closed Work Items precondition to prevent zombie work items from being used to avoid process checks on streams.
Recipe: Prevent enhancements from entering bug fix stream
Consider a team with two streams: a development stream where new features should be added and a support stream which should only receive bug fixes. The process author wants to ensure that work items of type “Enhancement” cannot enter the support stream.
The process author can verify arbitrary work item tests with the Require Work Items to Match Query precondition. In this case, the user needs to create a query that matches all work item types except enhancements:
Blocked delivery attempts will link to the query, work item, and change set:
Arbitrarily complex work item queries can be used to verify tags, comments, approval status, ancestoral relationships, et cetera.
Copyright © 2012 IBM Corporation