Details
-
New Feature
-
Status: Resolved (View Workflow)
-
Major
-
Resolution: Fixed
-
None
Description
It would be cool if there was a button on a job's summary screen that you could click to Watch the issue, so you were notified when certain changes happened instead of having to configure the job and add yourself to the email list.
Could even take it one step further and under the user's options, allow them to set default Watch options.
Attachments
Activity
This may take more time as I need to consider security implications. General users shouldn't necessarily be able to Watch any job they want. I guess perhaps read permission would be the minimal requirement, but I'll have to look into it.
The other thing that user should have ability to specify triggers for watch.
That's the plan, I just need to decide if I only want users to be able to watch according to already existing triggers or not. Adding new triggers may or may not be a good idea.
Yes, but that would only be if I added the settings to the job. If I added the settings to the user, then I think any trigger (in sandboxed mode) would be allowed.
I released 2.40-beta to the experimental plugins update center [1] last night with this feature. If you get a chance, please try it out.
1 - http://jenkins-ci.org/content/experimental-plugins-update-center
I see no watch buttons in job and got this stacktrace after opening user configuration.
javax.servlet.ServletException: org.apache.commons.jelly.JellyTagException: jar:file:/Users/Shared/Jenkins/Home/war/WEB-INF/lib/jenkins-core-1.586.jar!/hudson/model/User/configure.jelly:52:65: <st:include> No page found 'config.jelly' for class hudson.plugins.emailext.watching.EmailExtWatchAction$UserProperty$DescriptorImpl at org.kohsuke.stapler.jelly.JellyFacet$1.dispatch(JellyFacet.java:103) at org.kohsuke.stapler.Stapler.tryInvoke(Stapler.java:745) at org.kohsuke.stapler.Stapler.invoke(Stapler.java:875) at org.kohsuke.stapler.MetaClass$6.doDispatch(MetaClass.java:249) at org.kohsuke.stapler.NameBasedDispatcher.dispatch(NameBasedDispatcher.java:53) at org.kohsuke.stapler.Stapler.tryInvoke(Stapler.java:745) at org.kohsuke.stapler.Stapler.invoke(Stapler.java:875) at org.kohsuke.stapler.Stapler.invoke(Stapler.java:648) at org.kohsuke.stapler.Stapler.service(Stapler.java:237) at javax.servlet.http.HttpServlet.service(HttpServlet.java:848) at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:686) at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1494) at hudson.util.PluginServletFilter$1.doFilter(PluginServletFilter.java:96) at hudson.util.PluginServletFilter.doFilter(PluginServletFilter.java:88) at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1482) at hudson.security.csrf.CrumbFilter.doFilter(CrumbFilter.java:48) at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1482) at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:84) at hudson.security.UnwrapSecurityExceptionFilter.doFilter(UnwrapSecurityExceptionFilter.java:51) at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:87) at jenkins.security.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:117) at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:87) at org.acegisecurity.providers.anonymous.AnonymousProcessingFilter.doFilter(AnonymousProcessingFilter.java:125) at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:87) at org.acegisecurity.ui.rememberme.RememberMeProcessingFilter.doFilter(RememberMeProcessingFilter.java:142) at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:87) at org.acegisecurity.ui.AbstractProcessingFilter.doFilter(AbstractProcessingFilter.java:271) at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:87) at jenkins.security.BasicHeaderProcessor.doFilter(BasicHeaderProcessor.java:86) at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:87) at org.acegisecurity.context.HttpSessionContextIntegrationFilter.doFilter(HttpSessionContextIntegrationFilter.java:249) at hudson.security.HttpSessionContextIntegrationFilter2.doFilter(HttpSessionContextIntegrationFilter2.java:67) at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:87) at hudson.security.ChainedServletFilter.doFilter(ChainedServletFilter.java:76) at hudson.security.HudsonFilter.doFilter(HudsonFilter.java:164) at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1482) at org.kohsuke.stapler.compression.CompressionFilter.doFilter(CompressionFilter.java:46) at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1482) at hudson.util.CharacterEncodingFilter.doFilter(CharacterEncodingFilter.java:81) at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1482) at org.kohsuke.stapler.DiagnosticThreadNameFilter.doFilter(DiagnosticThreadNameFilter.java:30) at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1474) at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:499) at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:137) at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:533) at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:231) at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1086) at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:428) at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:193) at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1020) at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:135) at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:116) at org.eclipse.jetty.server.Server.handle(Server.java:370) at org.eclipse.jetty.server.AbstractHttpConnection.handleRequest(AbstractHttpConnection.java:489) at org.eclipse.jetty.server.AbstractHttpConnection.headerComplete(AbstractHttpConnection.java:949) at org.eclipse.jetty.server.AbstractHttpConnection$RequestHandler.headerComplete(AbstractHttpConnection.java:1011) at org.eclipse.jetty.http.HttpParser.parseNext(HttpParser.java:644) at org.eclipse.jetty.http.HttpParser.parseAvailable(HttpParser.java:235) at org.eclipse.jetty.server.AsyncHttpConnection.handle(AsyncHttpConnection.java:82) at org.eclipse.jetty.io.nio.SelectChannelEndPoint.handle(SelectChannelEndPoint.java:668) at org.eclipse.jetty.io.nio.SelectChannelEndPoint$1.run(SelectChannelEndPoint.java:52) at winstone.BoundedExecutorService$1.run(BoundedExecutorService.java:77) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at java.lang.Thread.run(Thread.java:745) Caused by: org.apache.commons.jelly.JellyTagException: jar:file:/Users/Shared/Jenkins/Home/war/WEB-INF/lib/jenkins-core-1.586.jar!/hudson/model/User/configure.jelly:52:65: <st:include> No page found 'config.jelly' for class hudson.plugins.emailext.watching.EmailExtWatchAction$UserProperty$DescriptorImpl at org.kohsuke.stapler.jelly.IncludeTag.doTag(IncludeTag.java:124) at org.apache.commons.jelly.impl.TagScript.run(TagScript.java:269) at org.kohsuke.stapler.jelly.CallTagLibScript$1.run(CallTagLibScript.java:99) at org.apache.commons.jelly.tags.define.InvokeBodyTag.doTag(InvokeBodyTag.java:91) at org.apache.commons.jelly.impl.TagScript.run(TagScript.java:269) at org.apache.commons.jelly.impl.ScriptBlock.run(ScriptBlock.java:95) at org.apache.commons.jelly.TagSupport.invokeBody(TagSupport.java:161) at org.apache.commons.jelly.tags.core.OtherwiseTag.doTag(OtherwiseTag.java:41) at org.apache.commons.jelly.impl.TagScript.run(TagScript.java:269) at org.apache.commons.jelly.impl.ScriptBlock.run(ScriptBlock.java:95) at org.apache.commons.jelly.TagSupport.invokeBody(TagSupport.java:161) at org.apache.commons.jelly.tags.core.ChooseTag.doTag(ChooseTag.java:38) at org.apache.commons.jelly.impl.TagScript.run(TagScript.java:269) at org.apache.commons.jelly.impl.ScriptBlock.run(ScriptBlock.java:95) at org.apache.commons.jelly.tags.core.CoreTagLibrary$2.run(CoreTagLibrary.java:105) at org.kohsuke.stapler.jelly.CallTagLibScript.run(CallTagLibScript.java:120) at org.apache.commons.jelly.impl.ScriptBlock.run(ScriptBlock.java:95) at org.kohsuke.stapler.jelly.CallTagLibScript$1.run(CallTagLibScript.java:99) at org.apache.commons.jelly.tags.define.InvokeBodyTag.doTag(InvokeBodyTag.java:91) at org.apache.commons.jelly.impl.TagScript.run(TagScript.java:269) at org.apache.commons.jelly.impl.ScriptBlock.run(ScriptBlock.java:95) at org.kohsuke.stapler.jelly.CallTagLibScript$1.run(CallTagLibScript.java:99) at org.apache.commons.jelly.tags.define.InvokeBodyTag.doTag(InvokeBodyTag.java:91) at org.apache.commons.jelly.impl.TagScript.run(TagScript.java:269) at org.apache.commons.jelly.TagSupport.invokeBody(TagSupport.java:161) at org.apache.commons.jelly.tags.core.WhenTag.doTag(WhenTag.java:46) at org.apache.commons.jelly.impl.TagScript.run(TagScript.java:269) at org.apache.commons.jelly.impl.ScriptBlock.run(ScriptBlock.java:95) at org.apache.commons.jelly.TagSupport.invokeBody(TagSupport.java:161) at org.apache.commons.jelly.tags.core.ChooseTag.doTag(ChooseTag.java:38) at org.apache.commons.jelly.impl.TagScript.run(TagScript.java:269) at org.apache.commons.jelly.impl.ScriptBlock.run(ScriptBlock.java:95) at org.apache.commons.jelly.tags.core.CoreTagLibrary$2.run(CoreTagLibrary.java:105) at org.kohsuke.stapler.jelly.CallTagLibScript.run(CallTagLibScript.java:120) at org.apache.commons.jelly.impl.ScriptBlock.run(ScriptBlock.java:95) at org.apache.commons.jelly.tags.core.CoreTagLibrary$2.run(CoreTagLibrary.java:105) at org.kohsuke.stapler.jelly.CallTagLibScript.run(CallTagLibScript.java:120) at org.apache.commons.jelly.tags.core.CoreTagLibrary$1.run(CoreTagLibrary.java:98) at org.apache.commons.jelly.TagSupport.invokeBody(TagSupport.java:161) at org.apache.commons.jelly.tags.core.ForEachTag.doTag(ForEachTag.java:150) at org.apache.commons.jelly.impl.TagScript.run(TagScript.java:269) at org.apache.commons.jelly.impl.ScriptBlock.run(ScriptBlock.java:95) at org.kohsuke.stapler.jelly.CallTagLibScript$1.run(CallTagLibScript.java:99) at org.apache.commons.jelly.tags.define.InvokeBodyTag.doTag(InvokeBodyTag.java:91) at org.apache.commons.jelly.impl.TagScript.run(TagScript.java:269) at org.kohsuke.stapler.jelly.ReallyStaticTagLibrary$1.run(ReallyStaticTagLibrary.java:99) at org.kohsuke.stapler.jelly.ReallyStaticTagLibrary$1.run(ReallyStaticTagLibrary.java:99) at org.apache.commons.jelly.impl.ScriptBlock.run(ScriptBlock.java:95) at org.apache.commons.jelly.tags.core.CoreTagLibrary$2.run(CoreTagLibrary.java:105) at org.kohsuke.stapler.jelly.CallTagLibScript.run(CallTagLibScript.java:120) at org.apache.commons.jelly.impl.ScriptBlock.run(ScriptBlock.java:95) at org.kohsuke.stapler.jelly.CallTagLibScript$1.run(CallTagLibScript.java:99) at org.apache.commons.jelly.tags.define.InvokeBodyTag.doTag(InvokeBodyTag.java:91) at org.apache.commons.jelly.impl.TagScript.run(TagScript.java:269) at org.apache.commons.jelly.impl.ScriptBlock.run(ScriptBlock.java:95) at org.apache.commons.jelly.tags.core.CoreTagLibrary$1.run(CoreTagLibrary.java:98) at org.apache.commons.jelly.impl.ScriptBlock.run(ScriptBlock.java:95) at org.apache.commons.jelly.tags.core.CoreTagLibrary$2.run(CoreTagLibrary.java:105) at org.kohsuke.stapler.jelly.CallTagLibScript.run(CallTagLibScript.java:120) at org.apache.commons.jelly.impl.ScriptBlock.run(ScriptBlock.java:95) at org.kohsuke.stapler.jelly.CallTagLibScript$1.run(CallTagLibScript.java:99) at org.apache.commons.jelly.tags.define.InvokeBodyTag.doTag(InvokeBodyTag.java:91) at org.apache.commons.jelly.impl.TagScript.run(TagScript.java:269) at org.apache.commons.jelly.impl.ScriptBlock.run(ScriptBlock.java:95) at org.kohsuke.stapler.jelly.ReallyStaticTagLibrary$1.run(ReallyStaticTagLibrary.java:99) at org.kohsuke.stapler.jelly.ReallyStaticTagLibrary$1.run(ReallyStaticTagLibrary.java:99) at org.apache.commons.jelly.impl.ScriptBlock.run(ScriptBlock.java:95) at org.kohsuke.stapler.jelly.ReallyStaticTagLibrary$1.run(ReallyStaticTagLibrary.java:99) at org.kohsuke.stapler.jelly.ReallyStaticTagLibrary$1.run(ReallyStaticTagLibrary.java:99) at org.apache.commons.jelly.impl.ScriptBlock.run(ScriptBlock.java:95) at org.kohsuke.stapler.jelly.ReallyStaticTagLibrary$1.run(ReallyStaticTagLibrary.java:99) at org.apache.commons.jelly.impl.ScriptBlock.run(ScriptBlock.java:95) at org.kohsuke.stapler.jelly.ReallyStaticTagLibrary$1.run(ReallyStaticTagLibrary.java:99) at org.apache.commons.jelly.impl.ScriptBlock.run(ScriptBlock.java:95) at org.apache.commons.jelly.tags.core.CoreTagLibrary$2.run(CoreTagLibrary.java:105) at org.kohsuke.stapler.jelly.CallTagLibScript.run(CallTagLibScript.java:120) at org.apache.commons.jelly.tags.core.CoreTagLibrary$2.run(CoreTagLibrary.java:105) at org.kohsuke.stapler.jelly.JellyViewScript.run(JellyViewScript.java:95) at org.kohsuke.stapler.jelly.DefaultScriptInvoker.invokeScript(DefaultScriptInvoker.java:63) at org.kohsuke.stapler.jelly.DefaultScriptInvoker.invokeScript(DefaultScriptInvoker.java:53) at org.kohsuke.stapler.jelly.JellyFacet$1.dispatch(JellyFacet.java:95) ... 64 more
I should have mentioned that you need to enable watching in the global configuration, and watching is only enabled for jobs that have email-ext configured already. I'm not sure why you are getting that stack trace, I'll look into it.
I added configuration to job, will check global configuration.
Found this button, it shouldn't allow choose types of recipients "developers" etc.
Please exclude "job" word from "Watch jobs" button text and url.
Ok, it looks like UserProperty implementations have to provide a config.jelly that shows up in the user configuration area. I'll look into this.
I have try this feature and it was good. But I don't understand why when I add a trigger on "Watch Job", I have the choice of who I would send a mail (developers, recipient list, culprits...). I think that is not usefull and this feature would just add me as receiver list.
Doesn't work, if we have no authentification on jenkins (exemple, a test instance).
Since I'm am reusing the UI for the trigger setup, the selection of recipients is still there, but only the person who is setting up the trigger will be emailed. If there is no authentication, how would the plugin know who to send the email to? The user would be Anonymous without login. The feature requires authentication in order to work.
My idea was to allow subscribe yourself, not allow somebody to configure job's notifications.
If you are anonymous, then doesn't allow to subscribe. (developers, recipient list, culprits...) - should not be available here.
You don't configure the job's notifications, it only subscribes you. If you are anonymous, then it doesn't allow you to watch a job. I don't want to have a separate UI for this vs. the normal configuration. so maybe I can set some variable to remove those items in the watch area.
Code changed in jenkins
User: Alex Earl
Path:
pom.xml
src/main/java/hudson/plugins/emailext/AttachmentUtils.java
src/main/java/hudson/plugins/emailext/EmailExtTemplateAction.java
src/main/java/hudson/plugins/emailext/ExtendedEmailPublisher.java
src/main/java/hudson/plugins/emailext/ExtendedEmailPublisherDescriptor.java
src/main/java/hudson/plugins/emailext/plugins/CssInliner.java
src/main/java/hudson/plugins/emailext/plugins/EmailTrigger.java
src/main/java/hudson/plugins/emailext/plugins/EmailTriggerDescriptor.java
src/main/java/hudson/plugins/emailext/plugins/trigger/AbstractScriptTrigger.java
src/main/java/hudson/plugins/emailext/plugins/trigger/PreBuildScriptTrigger.java
src/main/java/hudson/plugins/emailext/plugins/trigger/ScriptTrigger.java
src/main/java/hudson/plugins/emailext/watching/EmailExtWatchAction.java
src/main/java/hudson/plugins/emailext/watching/EmailExtWatchJobProperty.java
src/main/resources/hudson/plugins/emailext/EmailExtTemplateAction/action.groovy
src/main/resources/hudson/plugins/emailext/EmailExtTemplateAction/action.jelly
src/main/resources/hudson/plugins/emailext/ExtendedEmailPublisher/global.groovy
src/main/resources/hudson/plugins/emailext/Messages.properties
src/main/resources/hudson/plugins/emailext/watching/EmailExtWatchAction/help-triggers.html
src/main/resources/hudson/plugins/emailext/watching/EmailExtWatchAction/help-triggers_ja.html
src/main/resources/hudson/plugins/emailext/watching/EmailExtWatchAction/help-triggers_zh_TW.html
src/main/resources/hudson/plugins/emailext/watching/EmailExtWatchAction/index.groovy
src/main/resources/hudson/plugins/emailext/watching/EmailExtWatchAction/index.properties
src/main/resources/hudson/plugins/emailext/watching/EmailExtWatchAction/jobMain.groovy
src/main/webapp/help/globalConfig/watching.html
src/test/java/hudson/plugins/emailext/EmailTypeTest.java
src/test/java/hudson/plugins/emailext/plugins/CssInlinerTest.java
src/test/java/hudson/plugins/emailext/plugins/content/JellyScriptContentTest.java
src/test/java/hudson/plugins/emailext/plugins/content/ScriptContentChangeLogSet.java
src/test/java/hudson/plugins/emailext/plugins/content/ScriptContentTest.java
src/test/java/hudson/plugins/emailext/plugins/recipients/MockUtilities.java
src/test/resources/recipient-provider-upgrade2.xml
http://jenkins-ci.org/commit/email-ext-plugin/bb0053d79fec59f34d3014117883282d6c2239dc
Log:
Fix JENKINS-18567, JENKINS-25926 and JENKINS-25719
Added ability for users to watch a job.
Fixup the html content coming from CssInliner
Remove adminAddress field for global config
I've enabled the option in system configuration, but can't find any Watch option on the project page in Jenkins. And there is no documentation for this feature on the main help page for this plugin. Only cursory mention of it in the revision history.
Never mind. I found it where I didn't expect it. It's not in the main navigation on the top left, but you'll find it when you scroll down the categories in the job summary itself. I was looking at a multi-job so had to scroll down below the display of job status.
There still should have been some documentation added for the feature.
Interesting idea. I'll see what I can do.