#6543 closed enhancement (fixed)
Automate milestone->version
Reported by: | Owned by: | ebray | |
---|---|---|---|
Priority: | normal | Milestone: | 0.12 |
Component: | roadmap | Version: | 0.10.4 |
Severity: | normal | Keywords: | tracobject |
Cc: | osimons | Branch: | |
Release Notes: | |||
API Changes: | |||
Internal Changes: |
Description
It is fairly logical that a particular milestone, once completed, transforms into a product version, especially when it comes to the public face of a project (which Trac is usually part of). It would be handy if Trac were able to do this automatically - that is, upon completetion of a milestone, there should be an option to auto-create an equivalent version to log future defects against.
Attachments (1)
Change History (31)
follow-up: 2 comment:1 by , 17 years ago
comment:2 by , 17 years ago
Replying to Markus.Staab:
also it would be very nice, if the auto completed milestone could trigger a batch script or another python/php or whatever script, which then can create a tag/branch in the svn system..
Definitely not in Trac core: this is a specific usage of Trac/SVN, not a generic way to use them. However the RoadmapModule would need to trigger an event when a milestone is completed so that a plugin may implement such a feature.
comment:3 by , 17 years ago
Component: | version control → roadmap |
---|---|
Owner: | changed from | to
comment:4 by , 17 years ago
Milestone: | → 0.12 |
---|
I agree that this does not belong in the Trac core, and with the variety of uses that Trac is put to I doubt that milestone → version is a generalisation that holds water. 99% of our projects, for instance, deals with tracking a linear one-installation development (like web sites) where only the current production state matters. Plenty of milestones, no versions.
So yes, I suppose suppose the essence of this ticket is that we need IMilestoneChangeListener
in core, and allow plugin developers to do whatever it takes to provide this feature as changes are made. Perhaps accompanied by similar listeners for Component, Version and the various other enums. Not to mention changes to custom fields…
Setting it to 0.12 just to have it on the radar for next cycle.
comment:5 by , 17 years ago
#3035 closed as duplicate. Older ticket with some comments worth reviewing.
follow-up: 8 comment:7 by , 16 years ago
Hm, haven't seen this ticket before—I definitely like the idea. There shouldn't be anything in Trac core that does anything specific when a milestone changes, as that's just too dependent on anyone's given development process. But I can definitely think of a number of ways I would make use of an IMilestoneChangeListener
interface.
Any chance this can get into 0.12 if I submit a patch?
comment:8 by , 16 years ago
Cc: | added |
---|
by , 16 years ago
Attachment: | milestone-change-listener-r7550.patch added |
---|
An initial stab at this. Includes a sample plugin implementing something like the request in #7574.
comment:9 by , 16 years ago
Pretty much follows the model of ITicketChangeListener
. One could very easily write similar interfaces for Component, Version, and AbstractEnum, but at that point you're getting into GenericTrac territory…
comment:10 by , 16 years ago
Argh! you fool… you just lost 10 karma points!
More seriously, as long as you copy/paste the listeners around and you take care to introduce small differences, you're safe.
comment:11 by , 15 years ago
Dragging this issue up again, since I'm currently in the middle of writing a plugin that needs to react to changes to some of the enum types. Specifically, it maintains some configuration settings that are based on values in some of the enums, and when those enum values are changed I need to config settings to update accordingly.
So right now I'm using a RequestFilter
on the enum admin pages to make the appropriate configuration changes whenever an add, remove, or rename is submitted. This is hardly ideal for a number of reasons, but most importantly this is not something that should be tied to the UI. For example, if an enum is changed through the XML-RPC interface I'm out of luck. Fortunately, I have enough control over the situation that the RequestFilter
approach will work for now.
I could probably also get away with monkey patching, but I'm obviously not thrilled about that either.
comment:12 by , 15 years ago
I hadn't noticed this ticket before, and the patch for milestones looks good.
OTOH, I'm not sure if the solution is to add one I*ChangeListener
interface for every enum type, or if we should rather have a single IEnumChangeListener
interface, and user code checks the type of enum with isinstance()
. Strictly speaking, milestones, components and versions are not enums, but for the purpose of change notification, they could be treated as such.
comment:13 by , 15 years ago
Keywords: | tracobject added |
---|
Well, for the purpose of change notification, every resource could be treated the same:
class IResourceChangeListener(Interface): """Notify plugins that some resource in Trac has been created, modified or deleted. In the following methods, each `resource` parameter corresponds to a `Resource` object used for specifying what is being added, modified or deleted. It's up to the implementer to retrieve the data model object which is eventually associated with this resource, if needed. """ def resource_created(resource, author, created): """New `resource` created, at date `created`, by `author`.""" def resource_modified(resource, editor, modified, comment, old_values): """The existing `resource` changed at date `modified` by `editor`. `old_values` is a dictionary containing the properties of the corresponding resource prior to the modification. """ def resource_delete(resource, editor, modified, comment, old_values): """The `resource` was deleted at date `modified` by `editor`. `old_values` is a dictionary containing the properties of the corresponding resource prior to the removal. """ def resource_version_delete(resource, editor, modified, comment, old_values): """A specific `resource` version has been deleted, at date `modified` by `editor`. The `resource.version` corresponds to the version that has been deleted. `old_values` is a dictionary containing the properties of the deleted version of the resource. """
Note that for the resource_created
and resource_modified
, we could eventually pass directly the model object in addition to the resource, as when such an object exists, the notifying code already has it. If not, or if there's no model object associated to the resource, that model parameter will simply be None
.
That being said, the above proposal is not exclusive to the possibility of having more focused I*Listener
interfaces for the enum resources, like we already have for the 'wiki', 'ticket' resources (and even 'changeset' resources in the MultiRepos branch), if there's some advantage to that.
comment:14 by , 15 years ago
Definitely would prefer a single interface to rule them all. Too many of them feels like bloat, and means every new resource needs a new change listener interface to go with it. But I think last time I hinted at that I was reprimanded ;)
comment:15 by , 15 years ago
IIUC, the proposed interface in comment:13 requires that the changing object is a Resource
, which is currently not the case for enum ticket fields, and that's what the request in comment:11 was about. And I don't think it's worth making them full-fledged resources.
So this ticket is actually two requests:
- Create the missing change notification interface for milestones. This could be done as suggested in comment:13 with a generic interface, which could also be called for wiki pages, tickets, and all other resources.
- Create a change notification interface for enum ticket fields. Those are not resources, and would therefore either need a separate interface, or be converted into resources.
There's also the question of the component and version fields, which are neither resources, nor enum fields (although this is an implementation detail). They could be treated as such, though.
So yeah, I would implement the generic interface and have all our resources call that (in addition to the "legacy" interfaces), and implement a separate interface for enum ticket fields.
comment:16 by , 15 years ago
Not sure why enums couldn't be treated as resources. We have a plugin that we use internally that allows environment admins to create their own custom enums, and they're treated essentially like any other resource in Trac.
comment:17 by , 15 years ago
Even for ticket types, status, resolution, severity, and priority?
Though that sounds a bit extreme, the changes to the different values for these enums could indeed be advertised using the interface given comment:13.
I think the concerns of Remy were more that the above enums are not really resources, so if we would do this, we would certainly abuse the (admittedly vague) concept.
Then, versions and components are currently not much more, but they certainly lend themselves more to be considered as resources (i.e. anything you'd like to attach a wiki content to it ;-) ). Now some systems have descriptions for the status values… So yes, it's not that clear cut where to draw the line.
follow-up: 20 comment:18 by , 15 years ago
Personally I think the aspects of the ticket system should be confined to life in the ticket system - and likely also include custom fields. With the exception of milestones (and some half-feable attemt at 'component' and 'version' with some added fields), there is no unique restful URL that defines their presence nor a description to say what they are. With current resource system, it is the support for a unique URL and its presence in a rendering context that defines the resource - not if it has additional fields or meta-information.
I'd rather have a full-baked ticket field infrastructure, than water out the essence of the resource system in such a way that you need to verify if the resource has a url, if it has a desciption, and if it really points anywhere meaningful.
However, if one wishes to do so, there is nothing that stops the ticket system extending its support for resource identifiers:
Resource('ticket', 'component/component1') # or Resource('ticket-field', 'component/component1')
We'd need to make a generic page to display such resources with fields and option. And that would be followed by the request for supporting all ticket fields and options through security policies to filter access…
comment:19 by , 15 years ago
Cc: | added |
---|
follow-up: 21 comment:20 by , 15 years ago
Replying to osimons:
However, if one wishes to do so, there is nothing that stops the ticket system extending its support for resource identifiers:
Resource('ticket', 'component/component1') # (1) # or Resource('ticket-field', 'component/component1') # 2
Well, I don't think (1) makes sense (unless we accept free form identifiers for tickets and you want to address named ticket "component/component1"), and (2) is not really clear. I don't see what this buys you over:
Resource('component', 'component1')
Certainly if you're going to introduce some module that adds a component resource which is not the same notion as what a component is in the ticket sub-system (a versioncontrol "component"?), you're willing to add extra complexity to the system and that "other kind of component" should be using a different realm than "component".
Back to the topic, I think we can eventually put the two approaches together (IResourceChangeListener
and IEnumChangeListener
).
The same way it's quite doable to look at, say, a wiki page change from either the point of view of a IWikiChangeListener
(legacy or specialized view) or of a IResourceChangeListener
(generic resource change view), I think it could be possible to look at a milestone change both from the point of view of a IResourceChangeListener
and a IEnumChangeListener
(e.g. for plugins interested in any kind of enum changes).
follow-up: 22 comment:21 by , 15 years ago
Replying to cboos: I don't see what this buys you over:
Resource('component', 'component1')
The point being fields as arbitrary resources, and with custom fields and future expansion of the flexibility of ticket properties it means all defined fields will grab a realm. Which means we are likely to run into all sorts of conflicts with plugins that add realms - a not-too-improbable custom field 'build' will conflict with Bitten for instance.
I just want the ticket system to 'bleed' into other arbitrary modules depending on what the user decides to configure. I want it somehow contained to one or two specific realms.
comment:22 by , 15 years ago
Replying to osimons:
Replying to cboos: I don't see what this buys you over:
Resource('component', 'component1')The point being fields as arbitrary resources,
Ah, I see. But that's not what I'm proposing. I agree this would be cumbersome.
How I see it is that you have different types of fields for a ticket.
- free form strings (Cc)
- wiki text (description)
- values taken from an enumeration (property, severity et al.)
- relations to other resources (typically milestone)
The case of component is simply that currently it's only implemented as an enum (or is it?) and doesn't yet deliver what one could expect from a full blown resource. But conceptually it is much closer to a milestone than to a priority, so I would categorize the type of the component field as being a relation (to resources of realm "component")
If really there's a need to represent a specific ticket field as a resource, then it should probably be represented as a child resource of a ticket, as in:
Resource('ticket', 123).child('field', 'priority') # (#123) (#123's priority, as a sub-resource) # or: Resource('ticket', None).child('field', 'priority') # (ticket realm) (the 'priority' in general)
(such a need could arise for making the coverage of fine-grained permission even more precise).
So in this case yes, it's a bit like your (2) proposal.
… a not-too-improbable custom field 'build' will conflict with Bitten for instance.
If there's a custom-field build, then it could be meant to be a relation to a Bitten build, or not. It all then depends on the type of the field (relation or not).
But the potential for conflicts between names of top-level realm is real, as we could have different build plugins. I suppose the "first" plugin to come wins, others will have to use a more specific name (e.g. "buildbot-build").
I just want the ticket system to 'bleed' into other arbitrary modules depending on what the user decides to configure. I want it somehow contained to one or two specific realms.
I guess you meant "blend" ;-)
My point was that if another module decides to take well-established ticket module concepts for its realms (like "ticket", "milestone", but also "component" or "version"), then that module asks for trouble.
There's no question that other ticket field names (let alone any custom field) should never suddenly become top-level realms.
comment:23 by , 15 years ago
Cc: | removed |
---|
comment:25 by , 15 years ago
Milestone: | next-major-0.1X → 0.12 |
---|---|
Owner: | changed from | to
I have updated Erik's patch to current trunk, and added a few test cases, so I'll push it into 0.12.
comment:27 by , 15 years ago
Resolution: | → fixed |
---|---|
Status: | new → closed |
Slightly adapted patch applied in [8828], together with test cases for the new interfaces.
Thanks for the patch, Erik!
comment:29 by , 15 years ago
Owner: | changed from | to
---|
also it would be very nice, if the auto completed milestone could trigger a batch script or another python/php or whatever script, which then can create a tag/branch in the svn system..