Currently, I’m being widely involved in customization of Buildbot instances. Many questions arise, but no answers are usually available on the Web.
Recently, I designed a custom build step which by the definition needed to work with values from properties passed to it on the init time. The challenge was to make it understanding everything that can theoretically be passed – build properties (IProperty), plain values etc.
In this case, we can use ‘renderables’ list to specify mapping from variables that can contain properties to variables that are used to store rendered values.
We can use passed values without caring to handle it as property or some other renderable. Buildbot does it automatically
class MyStep(BuildStep): ... renderables = ['renderable1' , 'renderable2'] def __init__(self, passed_var1, passed_var2): self.renderable1 = passed_var1 self.renderable2 = passed_var2
Invoke the step in the build factory as:
MyStep('actual value 1', 'actual value 2')
Now we can use passed values simply as without caring to handle it as property or some other renderable. Buildbot does it automatically.
Thank you for writing this! Sadly the buildbot documentation is disappointingly silent on this topic other than a trac issue saying “we ought to document BuildStep renderables” (see http://trac.buildbot.net/ticket/2929 ) but sadly that issue contains no further explanation…
Other readers: There are lots of cases where you don’t need to do this magic (such as when the renderable is passed into ShellCommand’s command parameter which already knows how to do the right thing) but if you are writing a custom buildstep and need to manipulate the string value of a renderable in a complicated way (Interpolate can take care of basic concatenation) or the renderable is going into something that only expects strings and doesn’t know how to render everything to them first then what is outlined in the blog post is essential.
From what I can tell the renderables class attribute contains the names of those object attributes (i.e. self.) that will be rendered to normal strings by the time the start method is called. For example, while you’re still in __init__ the magic won’t have happened and doing something like a = passed_var.split(“,”) there will generate a Python error but will work when put in start() (so long as the renderables class attribute has been set correctly).
If you’ve stumbled across this post via a search engine (as I did) because you are having trouble with your custom buildstep dealing with renderables (such as Property objects) passed in as parameters not being manipulable as strings, then what is posted here solves your problem. Don’t be a fool like I was and dismiss it just because the work when passed to ShellCommand!
Thank you for your feedback, I also found Buildbot docs sometimes unusable! However, digging into the source code helps much 🙂