Edgewall Software
Modify

Opened 12 years ago

Closed 10 years ago

Last modified 3 years ago

#6543 closed enhancement (fixed)

Automate milestone->version

Reported by: charles@… 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:

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)

milestone-change-listener-r7550.patch (7.5 KB ) - added by ebray 11 years ago.
An initial stab at this. Includes a sample plugin implementing something like the request in #7574.

Download all attachments as: .zip

Change History (31)

comment:1 by Markus.Staab, 12 years ago

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..

in reply to:  1 comment:2 by Emmanuel Blot, 12 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 Emmanuel Blot, 12 years ago

Component: version controlroadmap
Owner: changed from Christian Boos to Christopher Lenz

comment:4 by osimons, 11 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 osimons, 11 years ago

#3035 closed as duplicate. Older ticket with some comments worth reviewing.

comment:6 by osimons, 11 years ago

#7574 closed as duplicate.

comment:7 by ebray, 11 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?

in reply to:  7 comment:8 by osimons, 11 years ago

Cc: osimons added

Replying to ebray:

Any chance this can get into 0.12 if I submit a patch?

I see no reason why not.

by ebray, 11 years ago

An initial stab at this. Includes a sample plugin implementing something like the request in #7574.

comment:9 by ebray, 11 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 Christian Boos, 11 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 ebray, 10 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 Remy Blank, 10 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 Christian Boos, 10 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 ebray, 10 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 Remy Blank, 10 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 ebray, 10 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 Christian Boos, 10 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.

comment:18 by osimons, 10 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 ebray, 10 years ago

Cc: hyugaricdeau@… added

in reply to:  18 ; comment:20 by Christian Boos, 10 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).

in reply to:  20 ; comment:21 by osimons, 10 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.

in reply to:  21 comment:22 by Christian Boos, 10 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 Jonas Borgström, 10 years ago

Cc: hyugaricdeau@… removed

comment:24 by Remy Blank, 10 years ago

This generic notification interface would be perfect for #7758.

comment:25 by Remy Blank, 10 years ago

Milestone: next-major-0.1X0.12
Owner: changed from Christopher Lenz to Remy Blank

I have updated Erik's patch to current trunk, and added a few test cases, so I'll push it into 0.12.

comment:26 by Christian Boos, 10 years ago

And for the IResourceChangeListener interface, see #8834.

comment:27 by Remy Blank, 10 years ago

Resolution: fixed
Status: newclosed

Slightly adapted patch applied in [8828], together with test cases for the new interfaces.

Thanks for the patch, Erik!

comment:28 by Remy Blank, 10 years ago

New interface documented in TracDev/ApiChanges/0.12@14.

comment:29 by Remy Blank, 10 years ago

Owner: changed from Remy Blank to ebray

comment:30 by Ryan J Ollos, 3 years ago

#11643 closed as a duplicate.

Modify Ticket

Change Properties
Set your email in Preferences
Action
as closed The owner will remain ebray.
The resolution will be deleted.
to The owner will be changed from ebray to the specified user.

Add Comment


E-mail address and name can be saved in the Preferences .
 
Note: See TracTickets for help on using tickets.