 Welcome, it's Jenkins documentation office hours. It is the 16th of August. Oh, we've got Kristen and Meg and Mark here. So what we were going to do is record an answer to a question that Dheeraj had last week so that he can watch it as his time allows. So what Dheeraj has done is he has created, Dheeraj created an integration test inside the configuration as code plugin and submitted it as a pull request. And there was some feedback from Tim Jacome saying, hey, you really need to test it this other way. You need your assertions need to do this other thing. And so what we thought we would do is have a session here. Let's use a debugger to go exploring and see how we would learn how to write one of these kinds of tests using the debugger to help us identify what's in Jenkins that could help us. So that was the idea. And so what I've done is I've brought up, I've got net, I'm gonna run it with net beans. And after I've played with a little with net beans, we'll have Kristen Wettstone do a little bit of experimenting with Visual Studio Code because Visual Studio Code is what Dheeraj uses. I'm not familiar with VS Code. So I have to do my work in net beans. And then we talk about the differences in the distinctions and hope that we learn something together by doing it. So the first idea was, okay, here is, let's see, I guess I should probably show the source code. So here is a get window. And if we look at the list of things, what I did is I took Dheeraj's code and I rebased it onto the master branch. So first thing that I observed was his code is a long ways behind. Let's see, let's look at it this way, get remote. If we look at his code and see where is it, slash view job filters demo, and then my code, what we'll see is his code is quite a ways back and his master branch is quite a ways back. So one of the techniques that I had to learn in dealing with multiple repositories in GitHub is that my master branch doesn't automatically get updated when a new release happens or when new commits happen. So I have to bring in the changes from the upstream repository to my master branch and push them. So he's based off of, he's committed, made three commits to an outdated copy of the master branch. And usually the developers would like things committed against something that is very near the top of the master branch. So all I did was take his changes and rebase them so that they're on top of upstream master. And so here's his change rebase, here's his second change and here's his third change. So when I did that, there was, oh, it doesn't compile. And so I've added some additional things to make it compile. This add a dependency on the view job filters plugin changes the code so that it adds a dependency on the view job filters plugin into the integration test POM file. Then while compiling it, this plugin has strict enforcement of check style. And check style means that the imports need to be, any unused imports need to be removed and the imports need to be in a specific order. So I fixed those. Then while I was in there, I formatted the file because check style was also complaining that the file contained tab characters. And so I fed it to a formatter that let me then not have tab characters anymore. And then I made, oh, and then I realized that while running the tests, there were some errors in the calls to the constructors that Dira should originally done that I needed to fix. So I fixed those. I now got something that compiles and runs. So that was the crucial thing is, let's get something that will run a test. So my step was, okay, I opened his test, view job filters test, and I can set a break point here. Let's, yeah, let's set a break point there. And now when I do a right click debug test file with NetBeans, what it's going to do is it's going to start the debugger and it will run the test until it hits my break point. Now, this isn't particularly important. What I'm doing right now, it's just to show that, yes, the debugger will stop where it's run until it stops and stop. Now, one of the things to be aware of here is that this thing called a JUnit rule is actually constructing a Jenkins instance. It's really creating inside the test a fresh Jenkins instance. And that fresh Jenkins instance can be referenced through this J variable and used to a certain thing. So here the test has stopped and I can inspect variables. So for instance, I can look at this.j and see that, hey, there's a configured read me with rule and it's got lots of stuff on it because attached to that thing is a Jenkins and now I'm just going to continue and let the test run. So I made a number of modifications to allow the test to pass because I like to see tests pass. And so in this case, the test passed for me. So that's a positive, good sign. However, what the comment came was that, hey, this thing is just constructing an object and that's not using the results of this configured with read me rule or annotation. What this configured with read me annotation says is, start this Jenkins configured with read me rule, read view job filters read me.md and use that as the definition of a Jenkins configuration as code. And then inside the test, we're going to assert the expected attribute values of the test. However, in his test, what he's doing is defining a new object and then asserting the content of the new object. So that new object is not the same as the object that's inside the Jenkins that was defined with this configuration file. Any questions so far? Boy, I'm droning on, sorry about that. Okay, so as part of the exploring, one of the things that I like net beans is I can now say give me a Jenkins and let's call it Jenkins and this thing will be J dot. So J is this configured with read me rule and now I'm going to say J dot and thankfully the IDE now gives me help. It shows, oh, hey, look, there's a Jenkins field on this J object. And so I'm going to click that and there it is. Now I'll be able to oops and the little red stuff here says I've got to fix that. So I need to import Jenkins dot model dot Jenkins. Come on. Okay, so the import is done and we can see, okay, here's the import it added with the little green highlight and here's this. Yes, so the idea is helping me giving me hints. Now if I run with the debugger and let's do the same thing again. So I'm going to say debug the test file. Now I'll have this variable Jenkins inside the current context that I can use the debugger's facilities to go exploring that thing to see what's available on it. And what's available on it may help us decode how do we find a build duration filter inside this Jenkins object. Okay, so here we are Jenkins and this thing has item listeners, computer listeners and a bunch of static data and inherited data. And so I can just go looking, see if I see anything here that looks interesting. What I was thinking is, okay, what we're testing is something about views. So I was thinking I should probably be looking for something called views in this list. And I don't see anything called views in the static stuff. So let's look in the inherited. And now we truly are getting into the spot where I just start exploring and look, okay, is there a views here? And what we've got, if I keep going down there's a views tab bar, okay. And there are nodes which are prob, oh, here we go. And here is views. Okay, so we've got a views thing and primary view here is all, okay. I remember the Jenkins UI has a view that's named all. So okay, this could be something useful. And in the views, now what I've got is there's an array of list views, length one that has in it. And now this is where earlier today I found this, there was a job filter, here it is. Here is the build duration filter associated with it. And I think this build duration filter and this build status filter and then this build this security filter are exactly what came from this view job filters, readme.md. Now I should really open that file, shouldn't I because now we gotta find it. And this is where I'm badly, terribly unskilled with the IDE. So let's go find that file. And maybe we look here, find. Okay, so there's the test. Ah, here we go, viewjobfilters.yml. No, that's not, I was expecting a file named readme.md. I mean, this certainly is a valid job filters.yml file, but that's not what I was expecting to find. So I must be looking for the wrong thing. Files, integration tests. I think it's in the demos folder. Demos, ooh, that's a good solution. Yeah, it was a little weird. It was a little interesting because I was looking for it too, so. Okay, so in the demos folder, and if I remember what this thing is showing me is only things that it's managing. So I've gotta go look at it differently here. This is where, okay, my usual technique is bring out the other tool and go look for it. Let's find it again, grab for it. Okay, so what I wanted was build duration because I assume the build duration will be somewhere in there. There we go. Okay, demos, view job filters, just like you said, Kristen, view job filters, readme.md. So when I look at this file, the source data that he's using says, okay, amount 60 days, latest, include matched, less than true. So those look like reasonable values and if we look inside the debugger here, I bet we will find where was my, let's see, not output variables. Here we've got, oh, come on, I was just here, views. Where are my views? Let's try it again. So inherited views. Okay, maybe we need to sort alphabetically. Here we go, views, list view. And now let's look at where my duration go back to views. Ah, here we go. Okay, ah, yes, there we are. Okay, so we've got job filters here and here is a build duration filter and it's got a less than value of true and a build duration float of five. And then I'll bet it also has some other values that it's inheriting like build count, amount, yes. So things it gets from the object it inherits from. So this, now the challenge for me was how do I ever get access to this views thing? And I assumed it was Jenkins.getView. Now that was, what was that? I missed it. The IDE gave me a hint and I ignored it. Jenkins.getViewsReturns, a collection of view. So like that. And of course the IDE is guiding me that I didn't finish entering all the imports. Okay, so stop the debugger and let's try it again. And maybe it's best for me to stop here and Kristen, do you wanna switch and show, take some time and show us some visual studio comparables? Do you do these kinds of explorations with video, visual studio or would you approach it differently? That kind of thing. Yes, sir, we can do some of the stuff. I'm just waiting for it to try to import the run and debug, which allows us to be able to do that cool like breaking thing. Cause what visual studio code has to do is you have to explicitly say, because everything is run via plugins. I think that means it's kind of like that too, but it's very, it started its life out like very lightweight. So almost everything is a plugin. Follow Jenkins, follow Jenkins. So the running and debugging some of the stuff, especially for the certain Java tools is like a plugin. So it has to like, you have to basically turn it on. Okay, so you're waiting for it to enable. Yeah, so I'm waiting for it to, right now it's scanning the entire project. And I think because it's so big, it's taking a little bit longer. It says it's 64% done. So what that will allow us to do is be able to do the debugging stuff too. So it's thinking, but... Cool. Yeah. Well, so if you're okay with it, well, and that's great. So maybe you can help me here on the, as I'm looking for this. So what I see now is I've got, I've got a variable for views and I can look around at the variable for views. Now I wanted to see if I could get the job filters. So the view has one of its things is a job filters. And I wanted to see if I could get that set of job filters. Now, this is where I get really uncomfortable because I'm not entirely sure how to ask that question to Jenkins. How do I ask from code? So views. Well, okay, so views is a collection. So we have to get the first item out of the collection. Oh, oh, oh, right. Oh, thank you. Right, right, of course, right. Why didn't I think of that? Excellent. So the first is I need to do a get or a views. It's a collection. So yeah, I need, I don't, they didn't offer a get views. Oh, come on, you silly thing. Trying again. Views. Please wait. Oh no, it's taking views from my stuff that's still working. No, see, I don't want, okay, how do I, how do I read from the collection? I mean, it's. I thought it was good. Yeah. Okay, so I could either street. I'll tell you right now. I'm so used to JavaScript that I was like, just put it in brackets and get the first one. I was like, just get the first one. I hope. No, so it's okay. How do I, all right. Java. Java read first. Oh, wait a second. It's a collection. And therefore it's no promise about any ordering. Well, I think it only has one element. Yeah. So, but, but I have to get an item from a collection. And now that means I've got to go, go. Okay. I've got to use the for each thing. I've got to iterate over it, right? It's not, it's, I can't. Okay. For view. So this is, this is, because I was assuming, oh, I'll get it by index, but of course it doesn't have a concept. This collection doesn't have a concept of ordering. So there isn't a way to do. Okay. So this is now it's saying view. Okay. Now we go maybe. All right. So this is, I would like to get, I would, in a perfect world, there would be something about get job filters, but I don't see it. So is it likely to be a descriptor that I need to ask for the list of descriptors? And there's no filter. Just like a straight get filter filters. I don't see one. Let's see. Get people, get in-denter, get properties, get Q items. I guess it could be a property. Is filter executor executors? Get view, get this set description. Okay. So I'm going to ask for the descriptor just because I want to see what, okay. And that is what type? What's the type of this thing? Describable, oh goodness. Describable. And this is one where I'm not nearly, okay. I think it's a, do I have to get it as a descriptor? Oh, no, it's a descriptor. Okay. So I got the wrong type. That's not right. So now back to help, having the ID help me with what? Okay, view dot, get descriptor. It returns a view descriptor. Okay. Okay. So, and of course I didn't import it. So we need to import. Okay. Now view descriptor dot. And here again, I was hoping to find something about filter. Nope. Oh, get job filters descriptors. Yes. Okay. So I think, and this is a list of descriptors of view job filter. Now, did it do it? And I'm sure there's a better way with, if someone who was really serious about the ID, it would automatically complete all the things. All right. So I'm at a point where I think I'm ready to try again. And this time get, hey, I can, this time I can get something. So this should be a descriptor of a view job filter, right? So now if I do a debug test file again, test file again. Now I admit this is a terribly inefficient way to do it. Smarter people probably have much better ways to do it, but for me, the ID is helping me explore to see, okay, where might I go from here and how might I use this and what could I do with it? I assume I could have also gone and read Java doc and found it somehow that way. Oh, I didn't set a break point correctly. Sorry. Try it again. I'm at a break point right here. Oh, yeah. So I've got this descriptor list, which has a whole bunch of things in it. Okay, so this surprises me a little. It's got the all jobs filter first and then build duration filter, build status filter and some others. Okay, so I'm not sure. So Kristen, how should I be interpreting this? Because this is a lot more things than I was expecting to find. I was assuming this would give me... Oh, oh, wait a sec. Those are... This... Oh, sorry. Go ahead. No, no. The first thing I think about is that I recognize those from trying to figure out those are like documents, almost like documentation tags that I think are inside of the filter. Like those are classes. Right, okay. So the fact that there are extra of them is not a big shock. So if that filter has extra, especially the help... First thing is pipeline steps where they have the descriptor info class and it's usually a lot of documentation that can help figure out what's going on with the build status, but it's not gonna be able to help us with this particular... It's a lot of extra stuff. Well, okay, and these are descriptors and descriptors are usually inside the thing we want to test, right? They're usually a subclass or an interior class. What do you call that? It's a... They're nested inside the thing I really want to get to because I want to get a build duration filter, not a build duration filter descriptor. So I... Oh, wait a sec. Maybe this is the... Maybe I'm just doing it wrong. Okay, so what I've got is I've got... We had views, right? I don't know what we're just looking for. Yeah, so we use the view descriptor. So maybe I'm not... I shouldn't be looking at view descriptors at all. Maybe this should, instead of view descriptors, it should just be looking at something else on the view. Sure, yeah, let's figure that part out. So usually my strategy when I start to get too complicated is probably not the correct one, but sometimes I go to... I look in GitHub and see if other people have written the test, like what I'm trying to do. Right, right, absolutely. And then I just like, okay, what am I trying to do? And then I just kind of like... It's almost like kind of like looking at Java docs or Java docs with examples. And it probably would be helpful to actually... Like to like look at the Java docs that's nicely published on our website would probably be like another good check. But I do like this exploring with the tool because like being able to poke around and see what's there in real time is pretty helpful to understand what's happening with your test. Yeah, so... It's working. It's just we need to figure out how to get it into the test. You know, because we see that they're there. Right, right. That's the other elegant thing, right? Is by exploring here, I see, hey, here's the job to job filter for build duration filter, build status filter and security filter. They really are there. And they have the expected values. Dheeraj, thanks for joining us. Sorry, we've just been going ahead. We figured you could watch the recording. Yes, thanks a lot. And I'm sorry for being late. Oh, no problem. We've been having more fun just exploring and looking to see... So we'll let you catch up later. You can watch the recording or look at the notes. I created a separate branch and had to make a number of changes in order to get your code to compile. And as part of this exercise, we've been doing some exploring, looking to see, okay, what could give us what we need? So here you see, let's get the list of views. And then there's only one in the whole list. So it's not a big list. There's just one view here. And so we iterate over that view and start looking inside the view to see what we could do with it. And that's where we've been sort of perplexed because what we wanna get to is these job filters and the job filters that are right there. The question is, where's a method that will let me access the job filters? And okay, it's a describable list. So maybe, Kristen, what do you think? Could it be that I, well, but here is the get job filters descriptors method call. Well, okay, let me, that's groovy. I was just like, is there a way that let me see if it's just doing the searching for examples on GitHub, seeing if it's possible to have just to get job filters. So I don't look at Java classes. So when we set, or when we got the, so there's a class called list view, which you can get the job filters from. Okay, so if I can get something that will give me back a list view. And it does give you a describable list with view, job filter, and then the descriptor. Okay, so if there's a... Well, I was looking to see if we got, if we were up to another level. So when we got our view collection, if we needed to somehow make it a list or if there was a way that you could add a static method. Oh, list view extends view, have a mind. I thought, darn it, so close. It looks like it's a subclass, not a superclass. Well, but isn't, I bet view is probably an item, isn't it? Well, I guess it doesn't matter. Okay, so we've got a, we can get a view descriptor here. We could get a view property. I wonder. So it doesn't appear that view has top filters as a, oh no, list view, okay, so it is a list view. So all you have, or depending on the version, I think all you have to do is say, get job filters. View. Because I'm looking at this when you're back, if we're looking at list view, and what version are we running against? Two dot, so what version of view, job filter plugin, or of Jenkins? Or Jenkins, because list view is in Jenkins core, though. And if I remember, this is based on two dot 249. Okay. But you're saying that there is a get job filter. There is on master, so Jenkins two dot 249. And that's not something just from the view job filters plugin, it's really. Right, like it's in Jenkins core, there should be a get job filters that there. Right, there it is, okay. I see it on the two dot 305, Java doc, okay. And now usually there's an at since that should have been added to that API. Okay, so this is on a list view object. So don't I still. In the code for two dot 249. Yeah, so somehow I need to get a list view out of. Well, isn't that what you've got? Right, like, because the first, if you scroll, see the in your variables section, or in the box down below, not in the code, but in the bugger, see the zero or scroll back up a little bit. Okay, so you have. Yeah, so. The view is absolutely a list view. Right, so. Okay, all right. So all we need to do is cast it. Okay, so list view. Okay, don't tell anybody I did such a terrible thing. Okay, but that now gives me a list view. Yeah. And now you've say right now, I've got to get job filters right there. And that will get exactly what we're looking for. Okay, all right. So knowing that and that the debugger hinted to me, hey, there's a list view here because look at this, it tells me the type. So instead of using the more general purpose, the more generic view, I said, fine, make it a list view like it is. And then, okay, now let's get that code. It was list view dot get job filters. And it is a describable list. And my ID is not helping me there. I need to learn more about how to do that. It has a long. Okay, it's a describable list of view job filter. Oh my God. Describable list describable of view job list. Filter. And I'm sure that's not the right way. Describable list. Okay, describable list we need to import. Okay, so back to writing a code dot get view. Get job filters, describable list of view job filter, comma descriptor of view job filter. Do you know, I'm sorry if this is- Let's figure out our class. Oh, sorry. I'm so sorry. No, go ahead. Get list done. I was like, I don't think that's how we'll be able to get the class that you'll need to cast. Cause- Right, exactly. Unfortunately, we gotta do a little bit more casting. This should be. I mean, okay, I'm gonna run the debugger up to, I'm gonna stop this debugger and run it up to there. And we're gonna look at A, right? Because I think that's the idea, right? Is now that will be, at least there's a chance that's the thing we need or that that list of this describable list has inside it our job filters. Okay, now A looks like A is a describable list. And there it is. Look at that. The first entry is a build duration filter. The second is the build status filter and the third is the security filter. Yes, victory. I think this is great. Okay, so now the real question is, okay, what do we do here? And for instance, I could say, talking about doing dirty tricks, I could say I want a variable build duration filter. Okay, so duration equals null. And now here duration equals, and this is terrible because, oh, oh, oh, I can do the get by class type. Look at that. That's a describable list. Oh, this is great. Right. Okay, so I can actually ask for it to get me the build duration filter, right? I think that's what I can do here, isn't it? I can say give me the thing that is one of these. Now, this is gonna prove me completely wrong because maybe I need a dot class. Is that now stop and let's try our debugging again because I really wanna see this. Sorry everybody that we're taking all this time with me playing with the debugger. Oh, this is good. Cause like, I think that we're like, look, we would never have seen that if the debugger didn't show us like the actual class of zero. Right, right. Yeah, letting the tool help us and say, okay, show me what the class structure is. Right. So, Dheeraj, while we're waiting for this thing to hit the break point, do you have time that you and I could talk even after the scheduled end of our session about the blog post? Yes, of course. Super, thank you. Sure. I would like to, I'm so sorry. Like at the, I think my computer realizes that we're recording a demo right now and it's still not finishing this refresh. I restarted, I even closed it because I was like, okay, maybe it froze or something. And I restarted it, it's at the same point. So I don't know what it's doing, but yeah, I can talk about it a little bit if you want me to or... Well, so for me, no problem because I think we've achieved at least what I was hoping to achieve. I think we've achieved it because, all right, so what we've got here and Kristin, you were exactly right, this a.get, this thing. Now, so I declared a build duration filter up here and walked through this and assigned duration to that one. And now I could hear, I can just do this and say, whoops, assign this to duration. And now I've got, I'm ready to do assertions on this thing. Now, that's totally dirty trickery, right? In no way should you submit something to the code that does that. But this lets me explore it and see, hey, does this behave the way I'm expecting? Yeah, and if it makes you feel a little better, Mark, I am looking, I've tried after we did this and I tried to see if I could find a test where they did something like this and there's a lot of casting going around with someone else, at least another test that I found. Okay, so but you did find a test that does this kind of thing. Yeah, the view job filters plugin. Yeah, which makes sense because that's the plugin we're using here. So that's really good, okay, great. So their test also does have a cast, like a cast for getting the list of the job filters, so. Okay. So don't worry, we're okay with our casting. So my guilt should not be terribly guilty. Exactly. Okay, so, but now, and now this is now asserting the thing that was generated by the README, instead of asserting the thing that was in this constructor. So we've got it testing the way that we would have hoped it tests. So that means we don't need this junk, okay? But we do need a status filter. So I think we need the same kind of thing here where we say build status filter, status equals no. And then we're going to do the same thing here and say status is and this one. And seriously, Dheeraj, you must not take this as an example of how the test should actually be written, but the trick, I think the technique is going to work for us of, okay, we go find the Jenkins, we get the list of views from Jenkins and then iterate over the list of views and take the value for duration. Now, in this case, what's this doing? It's relying that the list is of length one. And then that's a terribly dangerous thing to do, right? We should probably be asserting much more about how long is the list and what's the content of the list, et cetera. But for purposes of exploration, I think we're okay. Let me read this. I feel it's really lovely to see some board in Docs Officer. Well, I'm glad that you're not humiliated by watching my poor skills. Hey, I'm enjoying it. It's like a movie to me. It's very kind of you. It's very fun to do pair programming. Yes, yes. Especially when you get to discoveries, it feels like extra special. It's like, yes. Well, and I'm deeply in love with pair programming. So absolutely no question there. The time I spend pairing is just intensely valuable. Okay, so now this, oh, yes, good. Okay, so let's try it. Again, dirty trickery has been applied. Let's just run it and not even bring up the debugger. Let's just see if it passes the tests. Okay, so this is the noise from the Jenkins rule. Instantiation exception. Oh, this is Mark Waite's guilty problem elsewhere. And there it is, test passed. Okay. Well, that's a new problem. I was like, we didn't see that one at all. No, well, and that one is, that one is there's something going on in the SSH server plugin that I've been working with that as part of the Get Credentials Binding GSOC project. So it's all sorts of interesting. Cool. All right, so this I think is at least a beginning of, now let's fix the imports, because one of the things we learned, Dheeraj, when we went through this earlier was that this particular plugin has strict enforcement of check-style rules. And because it has strict enforcement of check-style rules, it enforces that, for instance, all of the imports must be in alphabetical order. And the static imports must follow the non-static imports and it's got things like that. So you have to be, oops, what did I just do? You have to be careful that not only does it pass inside your ID, but then you run it from the command line and be sure everything works there as well. Oh, okay. So the static import should be below the normal imports. In this particular plugin, yes, they there, and that's one of the things that plugins are allowed to sort of shape themselves to the way their maintainers want them to be. And in this plugin, they've chosen that they want certain check-style rules strictly enforced and they will fail the bill if you don't match their check-style rules. Okay, so ID does not do that automatically, right? We need to do this. It, well, in this case, I think it did, I think it retained them ordered. M, M, U, V, yeah, so I think it did it. I think NetBeans did, I'm not sure about others. Now, I had originally, when I was working on this, had used Emacs to do it and I just sorted things alphabetically with Emacs. And how did you realize that this is the necessity to do? Like it did it. Oh, I ran a compile and it failed the compilation. So I ran a command line compile and it failed to compile. Okay, got it. All right, so let's commit this and rough prototype of working, of reading Jenkins instance for the assertion, for object values, how about that? And then what you can do, Dheeraj, is you can, I'm gonna push this change to my repository and you can then get access to it and see, you can see the differences. Please. All right, now my apologies to everybody. We're now an hour and seven minutes beyond our, or seven minutes beyond our planned limit. I've gotta have some time with Dheeraj to talk about our proposal for a blog post. The rest of you don't have to stick around if you don't want to, but I think he and I need to chat about that. We had other topics, so we had Java, this one was the one I needed to talk to. And I'm not ready to talk about Hacktoberfest, so that's just me being embarrassed. Anything else, Dheeraj, that you feel like we need to discuss other than Java 11 and default Docker images? No, nothing from my side. I just wanted to say sorry for being late because I need to say it or else I would not be able to sleep. So I'm sorry for being late. I don't know why it was raining. That's why I forgot to wake up on time. So thanks for your time, I think. Absolutely no problem. We are all volunteers. We all absolutely get to have real lives outside. So good for you. That is not a problem in any way. Thanks for being here. You didn't even have to attend today at all if your time wouldn't allow. So don't be at all shy about that. Oh dear, what did I just do? I thought that should have redirected. Oh, you did finally. Okay, good. I learned about the debugger as well because I never took it seriously before this and now I realize that it's very useful. So thanks for that as well. Yeah, and thanks for asking the question last week and inspiring us to do the play. It's been helpful for me and I think Kristen has discovered some things in her exploring. So thanks very, very much. Okay. Okay, so the crucial thing for me, Dheeraj, is we've got, here's what I had, and maybe what we'll do is let me bring it up in running because it's better if we can see it on the webpage. So just a minute, let me get the site running and we'll look at it. Okay, now we've got it. Okay, so the blog post that you and I are proposing here is, okay, I did this picture just hopefully for some visual interest and now the text of the thing talks about controllers will use Java 11 by default, agents will use it by default, and now the agents, we're not gonna make the transition. It'll take us as much as two weeks, I fear, to do the transition for the agents. There are some Docker tags that we are no longer going to update, specifically around CentOS 8. And Windows 1809 Docker ranges have stopped. Are you okay with those, the messages that we've got in there? Is that, does that look okay to you? Yes, the link, the font and everything is great, BW. Okay, yeah, so this link, now I'm doing a little bit of a cheat here. So this hyperlink that says Jenkins 2.307, it jumps into this change log page and uses an internal destination that doesn't exist yet until your change log gets merged and we release 2.307 tomorrow. So I'm intentionally putting that hyperlink to it jumps into the page but doesn't show the correct content yet. Same for this one, it will jump into the LTS change log, but of course we haven't published 2.303.1 yet, so it's not there. Right, and about 2.307 that I'll be working right now. So do it, should I be working normally as I work on change logs or I need to add something special? I don't think you need to add anything special, just do the usual because, well, you know what, actually you asked a great question because there is something we could do. Let me show you the example of what we could do that might make it more visible to readers. Glad you asked. Okay, so if we look at the download page here and the change log, now if we look at, you see this yellow box, the yellow backgrounded box, there are ways to put those into the change log entries like this one and maybe we should do that for 2.307 is point to this blog post from the 2.307 change log. What do you think with that? Do you think that would help readers if they see a yellow block here that says, hey, the Docker image is now using Java 11 with this? Totally, I think that's a great idea. It's more visible. So let me show you how you do that and then you can do it yourself, but you just have to know where to look to find it. Okay, so let's look in content, change log. Nope, underscore change log, we need the data, data. No. Okay, where is it? You'd think I would remember it, all the things that I've done with it. Content, underscore data, there we go. Okay, so if we look here, I think if we just grab this text, so as described in the, and now if we search backwards for that, as described, okay, here we go. There is this thing banner that we can insert into a change log and that will put the yellow box up at the top. So, and if you're willing to do that, that would be great because then we get a way of highlighting, hey, this now has a different JDK and a different Java. Absolutely. Great, okay, thank you. Also would we need to add the link to the blog that you have published? That would be great as well, right? I think we should, and in order to make that doable, I'm gonna go ahead and merge this blog post because Tim has approved it and you and I have reviewed it, so I think we're gonna go ahead and merge it. That way when you update from upstream, you'll see that blog post so you can link to it with confidence. So it's merged now. So in the next 10 or 15 minutes, it should become visible. So what should I be writing there in the yellow box? Like, hey, this is a new change or something like, can you help me out? Yeah, I would steal the text from the blog post maybe. So maybe just say, Docker images provided by the Jenkins project, will use Java 11 instead of Java 8 by default, something like that, that sentence there. Meg, any recommendations? Yeah, what I like to post, what I'm wondering is how do I know whether that hurts me or affects me? Because there's something else where it tells me differences that are given to me like my builds may fail because of this or whatever. Oh, that's a good thing. That should probably be in this blog. So that text will link to this blog post, but this blog post really would benefit by having, hey, here's the impact of it. Yeah, because this is too much news and not enough actual impact, isn't it? Right, I mean even for starters my basic Java statement that I used to start Jenkins, is that the same? Well, in this case it is because when you run a Docker image, you don't get any control over which Java version, you're stuck with whatever version we did. Okay, okay. But impact is not covered in this blog and that's a problem, it should be, right? This is just, this is informational, good insight that we should probably put something here about impact, not just about, you know, so okay, there is some where it says if you want Java 8, you need to do this. But what it doesn't say is things like if you need to run a build with Java 8, you can still compile with Java 8 even though the agent is running Java 11, just choose a different tool. Right, and what the, and it made, I mean, there's probably some place out there a fairly detailed list of the differences between Java 8 and Java 11 that maybe we could look at. Well, certainly for the Jenkins project there is if we look at Java 11 here, running Jenkins on Java 11, this page should probably be, well, I don't know if this page justifies because there's not a lot of content here. Yeah, so it's good suggestion. Let me think some more about if we should put additional text into that blog post that guides them how they can do, how they can have a better experience with Java 11 if they have some problem. Yeah, so here are some good warnings for people related to Java 11. Yeah, this one may also need some visiting. Yep, thank you, found more things we need to fix. IDRsolutions.com, Java 8 versus Java 11, what are the differences? Yeah, and those kind of things are usually focused on the programmer. Right. And in the Jenkins context, they don't have to think about that level because the code is already adapted, but they do need to think about things like JVM versions on agents, the non-existence of Java Webstart. So there are some things that are in fact different between Java 8 and Java 11 that matter to a Jenkins user. And the positive, I think Java 11 seems to be significantly faster than Java 8. And I can't vouch for significantly, but it's certainly, for example, it runs very, very well on the ARM architecture. Java 11 is, and it's available for system 390 mainframes, whereas Java 8 by default doesn't run with acceptable performance on system 390 mainframes. So yeah, the Java 11 is a nice upgrade for most people. So, Dheeraj, I think we've got the plan for your steps. You'll work on the 307 change log? Yes. Okay, super. All right, and I'm sorry. Go ahead. Yes, so I was wondering if we, if I can write a blog on writing tests in configuration as a code. Oh, yes. The readme, so they fetch the results, Yamil from the readme file, right? That is something especially we discussed. Yes. Because even I found this, that very interesting to fetch from readme files. Excellent. I like that. I like that idea a lot. Awesome. So I'll watch the recording of this meeting and then I'll try to understand what happened and then try to reproduce it and then we'll start a draft blog and share it with you. Great. Thank you. Thanks very much. Awesome. Thanks. And it may be several days before I get the recordings posted, I've got a huge backlog of recordings I need to post. I'm sorry, but I've just been busy running the meetings instead of publishing their results. That's definitely fine. All right. All good. Thank you. Go ahead. Kristen, did you have something you need to say? Oh, no, no, you're good. Okay, all right. I think we're set then. Thanks very much. I'm sorry for an hour and 20 minute meeting. Thanks very, very much, everybody. Great results. Thank you. Thank you. Good meeting, guys. Mark, I'm throwing you some, you are some links that may or may not be useful. Oh, good. You see something official and I'm not finding that. So maybe if I keep making it. Yeah, the eight to 11 transition has been blogged and documented, et cetera. And it's been years since they did it. And so you may not find much of it. It may be going late. Yeah. Right. And then it sort of, I don't know, have we, in our internal testing, have we done things and found are there specific things with Jenkins where, you know, common things and changes? And it, but by reading carefully as I was listening to you, it sounds more like it's adding features, not like there isn't a lot of stuff that's getting. Well, and there are some things, for instance, that are absolutely impacts. And it reminds that this blog post needs to describe the impact because there are some plugins that just don't work with Java 11. It's a relatively small group, but there are some that simply do not work. And they're described here in this poll request that I submitted about this change and what we're going through, what we're doing. But I didn't mention them in the blog post and I should have. So if I should really go to this one and bring out, let's see, where is it? Backwards compatibility. So for instance, the Ruby runtime plugin just doesn't run with Java 11. And that means there are certain plugins, relatively small numbers of installations, but certain plugins that are just broken. They simply will not work. Now it's fun to see because, for example, the last release of this plugin was seven years ago. Wow. So the fact that it even executes is to me somewhat miraculous. Right. And I think others are even older than that. Some of them in this list have been nine or more years ago when they were last released. Okay. So I have grandchildren younger than some of these plugins. And yet out there, there are a few people for who these are critical. There are people who have them running, at least. I'm not sure critical, but there are people who have them running. We clearly have evidence they are running. They have to do some work to change if they didn't have them. Right. That's the most simple answer is either remove these plugins, some of them break for other reasons or stay with the old version or stay with Jaleid. Right. All right, thanks everybody. Terrific, thanks everybody. Talk to you next week. Sorry, Dheeraj, did you have something? Yes, just small questions. I'm sorry. So about the blog that I was saying, so is it worth my effort? So that people would be finding it helpful or it's something I'm doing for just by myself? I would guess that the configuration is code plugin and its testing technique is relatively specialized to that plugin. So most people won't be able to use that testing technique because it's somewhat unique to configuration as code plugin. Now, the using other tools to help you learn how to write tests, that might be more useful, but then again, I'm not sure how you would teach, how you would blog about what we did as in a pair programming session, right? Because what we did was needed Kristen's knowledge and my knowledge and we bounced ideas off of each other and I don't know how you blog about a pair programming session. So it's a good question. The technique that they're using is very good for configuration as code. I'm not sure that it's as useful for others outside of the configuration as code plugin. Okay, so what do you use this then? I think I'd probably, good question. I'd probably skip the blog post and focus for instance instead on helping us get the changelog automation all the way into the code so that then we can do reviews of proposals for changelog instead of having it create the changelog. Right, so that makes sense to me. So I'll then focus on that automation part then. Great. All right, thank you, Dheeraj. Anything else? No, no. All right, have a great day. Bye everybody. Take care everybody. Bye.