Groovy and Token Macro support for Email-ext

537 views
Skip to first unread message

Michael Bukosky

unread,
Jul 17, 2013, 11:45:50 AM7/17/13
to jenkins...@googlegroups.com, slide...@gmail.com
Hi,

I am currently trying to write a custom build/failure email for the Jenkins - Email-ext plugin. I decided to write the email as a groovy template because of the useful 'Email Template Testing' feature in Email-ext. I would like to use a combination of groovy script and the built in Token Macros. I am having a difficult time trying to figure out if I am doing this incorrectly or if it simply is not supported. Here is a simple code snippet

... <truncated>
 
<dt><font color="#FFFFFF" face="Calibri,Arial" size="2"><strong>Cause</strong></font></dt>
<dd><font color="#141414" face="Calibri,Arial" size="2">${build.causes}</font></dd>

<dt><font color="#FFFFFF" face="Calibri,Arial" size="2"><strong>Build log extract</strong></font></dt>
<dd><font color="#141414" face="Calibri,Arial" size="2">${BUILD_LOG_REGEX, matchedLineHtmlStyle=true}</font></dd> 

<dt><font color="#FFFFFF" face="Calibri,Arial" size="2"><strong>Failed Tests</strong></font></dt>
<dd><font color="#141414" face="Calibri,Arial" size="2">${FAILED_TESTS}</font></dd> 

...<truncated>

After much goggling, I found a few links that support my theory that these features are not supported yet.


If this is truly the case, I was wondering if it would be possible to use and test the snapshop release. I am a newer user to Jenkins and have not used a snapshot before. Does anyone know how to pull the (2.30.3-SNAPSHOT) and use it in my local Jenkins?

Thanks for all your help.

Mike

Slide

unread,
Jul 17, 2013, 11:55:36 AM7/17/13
to Michael Bukosky, jenkins...@googlegroups.com
When using macros in a groovy template, you need to use ${BUILD_LOG_REGEX(matchedLineHtmlStyle=true)} and ${FAILED_TESTS()}. Please give that a try. I should also be releasing a new version of email-ext soon, just have some final testing to do.

Slide

unread,
Jul 17, 2013, 11:56:30 AM7/17/13
to Michael Bukosky, jenkins...@googlegroups.com
Sorry, one typo in my email, it should be ${BUILD_LOG_REGEX(matchedLineHtmlStyle: true)}. matchedLineHtmlStyle is not a boolean though, so I'm not sure why you are using "true" as the value.

Michael Bukosky

unread,
Jul 17, 2013, 12:07:21 PM7/17/13
to jenkins...@googlegroups.com, Michael Bukosky
wow that was a simple fix. I have been racking my brain over this for the past few days. Thanks so much for all your help.

For reference here is my final snippet

<dt><font color="#FFFFFF" face="Calibri,Arial" size="2"><strong>Cause</strong></font></dt>
<dd><font color="#141414" face="Calibri,Arial" size="2">${build.causes}</font></dd>

<dt><font color="#FFFFFF" face="Calibri,Arial" size="2"><strong>Build log extract</strong></font></dt>
<dd><font color="#141414" face="Calibri,Arial" size="2">${BUILD_LOG_REGEX(matchedLineHtmlStyle:true)}</font></dd>


<dt><font color="#FFFFFF" face="Calibri,Arial" size="2"><strong>Failed Tests</strong></font></dt>
<dd><font color="#141414" face="Calibri,Arial" size="2">${FAILED_TESTS()}</font></dd>

Mike 

Slide

unread,
Jul 17, 2013, 12:18:40 PM7/17/13
to jenkins...@googlegroups.com, Michael Bukosky
One more thing, the email template testing should also work for Jelly templates, but I HIGHLY recommend using Groovy templates, they are MUCH better. I wish Jelly would die a horrible death after the amount of time I've put in to debugging templates :-)


--
You received this message because you are subscribed to the Google Groups "Jenkins Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to jenkinsci-use...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 



--
Website: http://earl-of-code.com

ejgre...@gmail.com

unread,
Oct 5, 2018, 3:25:06 PM10/5/18
to Jenkins Users
I know it's been a few years :) but I have a similar question...

How would I use the following Token Macro in a groovy template:

Git Commit:  ${BUILD_LOG_REGEX, regex=".*GIT COMMIT HASH = (.*)", showTruncatedLines=false, substText="$1"}

It works in a regular template but not groovy...

Thanks!

Slide

unread,
Oct 5, 2018, 3:38:39 PM10/5/18
to jenkins...@googlegroups.com
The general way to look at it is to turn the token syntax into what looks like a method call:

${BUILD_LOG_REGEX, regex=".*GIT COMMIT HASH = (.*)", showTruncatedLines=false, substText="$1"} 

Becomes:

BUILD_LOG_REGEX(regex:".*GIT COMMIT HASH = (.*)", showTruncatedLines:false, substText:"$1")



ejgre...@gmail.com

unread,
Oct 5, 2018, 4:44:56 PM10/5/18
to Jenkins Users
Thanks for your fast reply! Couple of questions...

1) Should I be putting that in Groovy brackets %> <%?
2) Am i supposed to escape the $ sign in the subsText clause?

I'm trying to get it to work but I'm getting exceptions...

Thanks!

ejgre...@gmail.com

unread,
Oct 5, 2018, 4:48:15 PM10/5/18
to Jenkins Users
Just to add to that:

If I do within groovy brackets %> <% 

I get the following exception:
Exception raised during template rendering: org.jenkinsci.plugins.workflow.job.WorkflowRun cannot be cast to hudson.model.AbstractBuild java.lang.ClassCastException: org.jenkinsci.plugins.workflow.job.WorkflowRun cannot be cast to hudson.model.AbstractBuild at hudson.plugins.emailext.plugins.content.EmailExtScript.methodMissing(EmailExtScript.java:69) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:93) at groovy.lang.MetaClassImpl.invokeMissingMethod(MetaClassImpl.java:944) at groovy.lang.MetaClassImpl.invokePropertyOrMissing(MetaClassImpl.java:1267) at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1220) at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1027) at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.callCurrent(PogoMetaClassSite.java:69) at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallCurrent(CallSiteArray.java:52) at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:154) at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:166) at SimpleTemplateScript111.run(SimpleTemplateScript111.groovy:31) at groovy.text.SimpleTemplateEngine$SimpleTemplate$1.writeTo(SimpleTemplateEngine.java:168) at groovy.text.SimpleTemplateEngine$SimpleTemplate$1.toString(SimpleTemplateEngine.java:180) at hudson.plugins.emailext.plugins.content.ScriptContent.renderTemplate(ScriptContent.java:151) at hudson.plugins.emailext.plugins.content.ScriptContent.evaluate(ScriptContent.java:82) at org.jenkinsci.plugins.tokenmacro.DataBoundTokenMacro.evaluate(DataBoundTokenMacro.java:208) at org.jenkinsci.plugins.tokenmacro.Parser.processToken(Parser.java:308) at org.jenkinsci.plugins.tokenmacro.Action$KiHW1UeqOdqAwZul.run(Unknown Source) at org.parboiled.matchers.ActionMatcher.match(ActionMatcher.java:96) at org.parboiled.parserunners.BasicParseRunner.match(BasicParseRunner.java:77) at org.parboiled.MatcherContext.runMatcher(MatcherContext.java:351) at org.parboiled.matchers.SequenceMatcher.match(SequenceMatcher.java:46) at org.parboiled.parserunners.BasicParseRunner.match(BasicParseRunner.java:77) at org.parboiled.MatcherContext.runMatcher(MatcherContext.java:351) at org.parboiled.matchers.FirstOfMatcher.match(FirstOfMatcher.java:41) at org.parboiled.parserunners.BasicParseRunner.match(BasicParseRunner.java:77) at org.parboiled.MatcherContext.runMatcher(MatcherContext.java:351) at org.parboiled.matchers.FirstOfMatcher.match(FirstOfMatcher.java:41) at org.parboiled.parserunners.BasicParseRunner.match(BasicParseRunner.java:77) at org.parboiled.MatcherContext.runMatcher(MatcherContext.java:351) at org.parboiled.matchers.ZeroOrMoreMatcher.match(ZeroOrMoreMatcher.java:39) at org.parboiled.parserunners.BasicParseRunner.match(BasicParseRunner.java:77) at org.parboiled.MatcherContext.runMatcher(MatcherContext.java:351) at org.parboiled.matchers.SequenceMatcher.match(SequenceMatcher.java:46) at org.parboiled.parserunners.BasicParseRunner.match(BasicParseRunner.java:77) at org.parboiled.MatcherContext.runMatcher(MatcherContext.java:351) at org.parboiled.parserunners.BasicParseRunner.run(BasicParseRunner.java:72) at org.parboiled.parserunners.ReportingParseRunner.runBasicMatch(ReportingParseRunner.java:86) at org.parboiled.parserunners.ReportingParseRunner.run(ReportingParseRunner.java:66) at org.parboiled.parserunners.AbstractParseRunner.run(AbstractParseRunner.java:81) at org.parboiled.parserunners.AbstractParseRunner.run(AbstractParseRunner.java:76) at org.jenkinsci.plugins.tokenmacro.Parser.process(Parser.java:68) at org.jenkinsci.plugins.tokenmacro.TokenMacro.expand(TokenMacro.java:204) at org.jenkinsci.plugins.tokenmacro.TokenMacro.expandAll(TokenMacro.java:234) at hudson.plugins.emailext.plugins.ContentBuilder.transformText(ContentBuilder.java:80) at hudson.plugins.emailext.ExtendedEmailPublisher.addContent(ExtendedEmailPublisher.java:852) at hudson.plugins.emailext.ExtendedEmailPublisher.createMail(ExtendedEmailPublisher.java:731) at hudson.plugins.emailext.ExtendedEmailPublisher.sendMail(ExtendedEmailPublisher.java:445) at hudson.plugins.emailext.EmailExtStep$EmailExtStepExecution.run(EmailExtStep.java:184) at hudson.plugins.emailext.EmailExtStep$EmailExtStepExecution.run(EmailExtStep.java:129) at org.jenkinsci.plugins.workflow.steps.AbstractSynchronousNonBlockingStepExecution$1$1.call(AbstractSynchronousNonBlockingStepExecution.java:47) at hudson.security.ACL.impersonate(ACL.java:260) at org.jenkinsci.plugins.workflow.steps.AbstractSynchronousNonBlockingStepExecution$1.run(AbstractSynchronousNonBlockingStepExecution.java:44) at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) at java.util.concurrent.FutureTask.run(FutureTask.java:266) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) at java.lang.Thread.run(Thread.java:748)

But without groovy brackets it just renders the text "BUILD_LOG_REGEX(regex:".*GIT COMMIT HASH = (.*)", showTruncatedLines:false, substText:"$1")"

Slide

unread,
Oct 5, 2018, 6:42:14 PM10/5/18
to jenkins...@googlegroups.com
Ok, I didn't realize you were doing this from a pipeline job (maybe I missed that). I am not sure how it will work with pipeline right now, I need to review the code.

Slide

unread,
Oct 7, 2018, 11:26:31 PM10/7/18
to jenkins...@googlegroups.com
Ok, I took a look at the source and it will definitely not work as is right now. The plugin in this one case is still assuming AbstractBuild instead of Run.

Elisha Greenwald

unread,
Oct 8, 2018, 12:03:44 AM10/8/18
to jenkins...@googlegroups.com
Thanks so much for looking. Really appreciate it. Any idea how to get the git commit hash some other way? I've tried a bunch to no avail...

Slide

unread,
Oct 8, 2018, 1:57:33 PM10/8/18
to jenkins...@googlegroups.com

Elisha Greenwald

unread,
Oct 8, 2018, 2:00:58 PM10/8/18
to jenkins...@googlegroups.com
Dude. You're the man! That would be awesome to get the tokens working in pipeline.

Thanks!

Reply all
Reply to author
Forward
0 new messages