How can a rung a command from an err-bot plugin from another err-bot plugin? - errbot

How can a rung a command from an err-bot plugin from another err-bot plugin?
run the "!dosomething" from another plugin on some type of scheduler.

You can try asking questions about errbot at gitter: https://gitter.im/errbotio/errbot

You can run a command from another plugin by calling the method directly. self.get_plugin(PluginName) after your plugin is activated will get you an instance of the other plugin. You can then call methods from that plugin.
from errbot import BotPlugin, botcmd
class MyPlugin(BotPlugin):
def activate(self):
super().activate() # <-- needs to be *before* get_plugin
self.get_plugin('Duo2fa').add_command('foo_bar')
#botcmd
def foo_bar(self, msg, args):
return "Bar" # will only run if --2fa is passed
This example is from https://github.com/andrewthetechie/errbot-duo2fa
on some type of scheduler.
Errbot offers pollers that let you run code on a schedule. Documentation is here: https://errbot.readthedocs.io/en/latest/user_guide/plugin_development/scheduling.html
You can also use another scheduling library and run it in a separate thread as part of your plugin. Here's an example in another plugin https://github.com/andrewthetechie/err-topic-a-day/blob/main/topic-a-day.py using apscheduler.

Related

Robot Framework - Use Listener to interrupt Execution

I'm currently implementing a way to manage execution of a test in robot framework using using tkinter and the builtin listeners.
I was able to make a Pause/Resume system relatively easily but I'm unable to make a Stop system.
In the RobotFramework UserGuide there is an example to insert keywords in test cases like this:
ROBOT_LISTENER_API_VERSION = 3
def start_test(test, result):
test.keywords.create(name='Log', args=['Keyword added by listener!'])
The issue is, that this is deprecated and doesn't work. I have the following error when trying to use this :
UserWarning: 'keywords' attribute is read-only and deprecated since Robot Framework 4.0. Use 'body', 'setup' or 'teardown' instead.
I don't know how to use Body setup or teardown to do what I want and I was unable to found any example similar to the deprecated one
Apparently I needed to ask the solution to find one by myself
So I just needed to make something like this :
test.setup.config(name="Fatal Error", args=["Force Quit"])
or
test.teardown.config(name="Fatal Error", args=["Force Quit"])

Groovy Script for JIRA-actions

I want to achieve the following using Adaptavist Scriptrunner in JIRA: A user comments on an issue and triggers a Scriptrunner custom script. If the issue is in the state "waiting for customer reply" and the user is a customer, trigger the workflow-transition "respond to question" and transfer the issue into the state "customer responded".
The Adaptavist Scriptrunner-Plugin uses Groovy as its language of choice for custom scripts. Unfortunately I have never worked with Groovy before and thus have no idea what I have to do to make this work. Out of the examples in the Scriptrunner docs I made the following:
import com.atlassian.jira.component.ComponentAccessor
def issue = event.issue
def workflow = ComponentAccessor.getWorkflowManager().getWorkflow(issue)
def wfd = workflow.getDescriptor()
def actionName = wfd.getAction(transientVars["actionId"] as int).getName()
This is supposed to get me the current workflow step but doesn't work. Would anyone be so kind, to help me write this script?
Cheers!
There's already available Script Listener called Fast-track transition an issue. You need just to create a new instance of it, bind it to your project and Issue Commented event, and add extra condition like issue.status.name == 'Waiting For Customer Reply' && currentUser == issue.reporter, and specify the transition. If you change workflow, you might need to update a listener too.
Also, these listeners, post-functions etc. are implemented as 'canned' scripts (classes implementing certain interface) which are available as plain groovy files in the plugin itself in the JAR file, they can teach a lot.

Jenkins Groovy Postbuild use static file instead of script

Is it possible to load an external groovy script into the groovy post build plugin instead of pasting the script content into each job? We have approximately 200 jobs so updating them all is rather time consuming. I know that I could write a script to update the config files directly (as in this post: Add Jenkins Groovy Postbuild step to all jobs), but these jobs run 24x7 so finding a window when I can restart Jenkins or reload the config is problematic.
Thanks!
Just put the following in the "Groovy script:" field:
evaluate(new File("... groovy script file name ..."));
Also, you might want to go even further.
What if script name or path changes?
Using Template plugin you can create a single "template" job, define call to groovy script (above line) in there, and in all jobs that need it add post-build action called "Use publishers from another project" referencing this template project.
Update: This is what really solved it for me: https://issues.jenkins-ci.org/browse/JENKINS-21480
"I am able to do just that by doing the following. Enter these lines in lieu of the script in the "Groovy script" box:"
// Delegate to an external script
// The filename must match the class name
import JenkinsPostBuild
def postBuild = new JenkinsPostBuild(manager)
postBuild.run()
"Then in the "Additional groovy classpath" box enter the path to that file."
We do it in the following fashion.
We have a file c:\somepath\MyScriptLibClass.groovy (accessible for Jenkins) which contains code of a groovy class MyScriptLibClass. The class contains a number of functions designed to act like static methods (to be mixed in later).
We include this functions writing the following statement in the beginning of sytem groovy and postbuild groovy steps:
[ // include lib scripts
'MyScriptLibClass'
].each{ this.metaClass.mixin(new GroovyScriptEngine('c:\\somepath').loadScriptByName(it+'.groovy')) }
This could look a bit ugly but you need to write it only once for script. You could include more than one script and also use inheritance between library classes.
Here you see that all methods from the library class are mixed in the current script. So if your class looks like:
class MyScriptLibClass {
def setBuildName( String str ){
binding?.variables['manager'].build.displayName = str
}
}
in Groovy Postbuild you could write just:
[ // include lib scripts
'MyScriptLibClass'
].each{ this.metaClass.mixin(new GroovyScriptEngine('c:\\somepath').loadScriptByName(it+'.groovy')) }
setBuildName( 'My Greatest Build' )
and it will change your current build's name.
There are also other ways to load external groovy classes and it is not necessary to use mixing in. For instance you can take a look here Compiling and using Groovy classes from Java at runtime?
How did I solve this:
Create file $JENKINS_HOME/scripts/PostbuildActions.groovy with following content:
public class PostbuildActions {
void setBuildName(Object manager, String str ){
binding?.variables['manager'].build.displayName = str
}
}
In this case in Groovy Postbuild you could write:
File script = new File("${manager.envVars['JENKINS_HOME']}/scripts/PostbuildActions.groovy")
Object actions = new GroovyClassLoader(getClass().getClassLoader()).parseClass(script).newInstance();
actions.setBuildName(manager, 'My Greatest Build');
If you wish to have the Groovy script in your Code Repository, and loaded onto the Build / Test Slave in the workspace, then you need to be aware that Groovy Postbuild runs on the Master.
For us, the master is a Unix Server, while the Build/Test Slaves are Windows PCs on the local network. As a result, prior to using the script, we must open a channel from the master to the Slave, and use a FilePath to the file.
The following worked for us:
// Get an Instance of the Build object, and from there
// the channel from the Master to the Workspace
build = Thread.currentThread().executable
channel = build.workspace.channel;
// Open a FilePath to the script
fp = new FilePath(channel, build.workspace.toString() + "<relative path to the script in Unix notation>")
// Some have suggested that the "Not NULL" check is redundant
// I've kept it for completeness
if(fp != null)
{
// 'Evaluate' requires a string, so read the file contents to a String
script = fp.readToString();
// Execute the script
evaluate(script);
}
I've just faced with the same task and tried to use #Blaskovicz approach.
Unfortunately it does not work for me, but I find upgraded code here (Zach Auclair)
Publish here with minor changes:
postbuild task
//imports
import hudson.model.*
import groovy.lang.GroovyClassLoader;
import groovy.lang.GroovyObject;
import java.io.File;
// define git file
def postBuildFile = manager.build.getEnvVars()["WORKSPACE"] + "/Jenkins/SimpleTaskPostBuildReporter.GROOVY"
def file = new File(postBuildFile)
// load custom class from file
Class groovy = this.class.classLoader.parseClass(file);
// create custom object
GroovyObject groovyObj = (GroovyObject) groovy.newInstance(manager);
// do report
groovyObj.report();
postbuild class file in git repo (SimpleTaskPostBuildReporter.GROOVY)
class SimpleTaskPostBuildReporter {
def manager
public SimpleTaskPostBuildReporter(Object manager){
if(manager == null) {
throw new RuntimeException("Manager object can't be null")
}
this.manager = manager
}
public def report() {
// do work with manager object
}
}
I haven't tried this exactly.
You could try the Jenkins Job DSL plugin which allows you to rebuild jobs from within jenkins using a Groovy DSL and supports post build groovy steps directly from the wiki
Groovy Postbuild
Executes Groovy scripts after a build.
groovyPostBuild(String script, Behavior behavior = Behavior.DoNothing)
Arguments:
script The Groovy script to execute after the build. See the plugin's
page for details on what can be done. behavior optional. If the script
fails, allows you to set mark the build as failed, unstable, or do
nothing. The behavior argument uses an enum, which currently has three
values: DoNothing, MarkUnstable, and MarkFailed.
Examples:
This example will run a groovy script that prints hello, world and if
that fails, it won't affect the build's status:
groovyPostBuild('println "hello, world"') This example will run a
groovy script, and if that fails will mark the build as failed:
groovyPostBuild('// some groovy script', Behavior.MarkFailed) This example
will run a groovy script, and if that fails will mark the
build as unstable:
groovyPostBuild('// some groovy script', Behavior.MarkUnstable) (Since 1.19)
There is a facility to use a template job (this is the bit I haven't tried) which could be the job itself so you only need to add the post build step. If you don't use a template you need to recode the whole project.
My approach is to have a script to regenerate or create all jobs from scratch just so I don't have to apply the same upgrade multiple times. Regenerated jobs keep their build history
I was able to get the following to work (I also posted on this jira issue).
in my postbuild task
this.class.classLoader.parseClass("/home/jenkins/GitlabPostbuildReporter.groovy")
GitlabPostbuildReporter.newInstance(manager).report()
in my file on disk at /home/jenkins/GitlabPostbuildReporter.groovy
class GitlabPostbuildReporter {
def manager
public GitlabPostbuildReporter(manager){
if(manager == null) {
throw new RuntimeException("Manager object musn't be null")
}
this.manager = manager
}
public def report() {
// do work with manager object
}
}

Pre send script in groovy for jenkins

i have two dependent jobs. i need help for groovy script in jenkins, for writing pre send script for email-ext plugin.
i want to check whether buid reason is upstream cause, then set cancel variable=true
But i don't know how to write if condition in groovy for jenkins..For seperate jobs, will there be any seperate classes in jenkins(so i can create instance and call upstream cause)
is there any way to check build cause of downstream job is due to upstream..
Please help me on this code snippet..
Use Build.getCauses() method. It will return a list of causes for the build. Loop over it and check if there is an object of hudson.model.Cause.UpstreamCause among them.
To get the build object, use the following code snippet:
def thr = Thread.currentThread()
def build = thr?.executable
FYI, here is a link to the complete Jenkins Module API.

groovy run() method documentation and purpose

What is the purpose of the default "run" method in groovy ?. i have read several text books found none of them describe using the run() method as a supported technique for invoking Groovy scripts (from other Groovy scripts).There are various supported techniques (e.g., GroovyShell, GroovyClassLoader, explicit call to Groovy script “main” method, etc.).
One of the ways to run groovy code is to have your class implement Runnable. When you invoke groovy MyRunnable at the command line, groovy will create an instance of your class and call the run() method. See the docs at http://groovy.codehaus.org/Running#Running-RunningGroovyscriptsfromthecommandline

Resources