 Hi everyone. For today's agenda, the first and foremost thing is the design discussion for authentication. So we have to discuss two things. The first is what information do we need to send to other plugins to create an authenticated client connection. And the second is to which plugins do we send that information. Because in the last meeting we had a discussion that we could delegate the responsibility of getting the size of repository from the branch source plugins to the base plugins, if they could be called base plugins, the GitHub plugin or the GitHub flag plugin. So while looking at the branch source plugins, I have seen that, so with the GitHub branch source plugin, I saw something which kind of helped me in generalizing how we could send the information to each plugin. So usually in the branch source plugins, the SCM source, what it does is when it needs the credentials, it looks for a class and for an example, the GitHub branch source would look for a username credentials class, username password credentials class. The GitLab branch source would look for a personal access token type of class. And then the context, so we need three things for authentication. First is the type of credential we need. Second is the context from where we need it. And the third is the credentials ID, which could be mapped to the credentials store. So the second thing, which is the context, so these branch source plugins, what they do is they get the owner of the SCM source, which is logical for them, because they are branch source plugins, so they would get that context and then find the credentials for that particular context. But what we need is we need to pass our own context, because for an example, a freestyle job will not be aware of any multi-branch project. So we need to pass our own context and we need these plugins to understand that and to take that in account and then find the credentials. So the GitHub branch source plugin already has a static method. So the GitLab branch source plugin did not have a static method to look for the credentials. It was linked to the instance of this SCM source. So my extensions, the extensions we implement are static. So there was no way I could borrow those credentials, which it searches in the SCM source owner, it search in the owner's context and then get them into our extension and that would, I think, would not be correct as well. So what I've done is I've done something similar. I borrowed what the GitHub branch source does. It provides a general method where you provide me, so that function asks for three things. It asks for the context. It asks for the, I will show you through the code only. So it asks for the context and then it asks for the URL for which we are asking this. It could be, it is generally the API URL. And third is the credentials ID. So I've done something similar for the GitLab plugin. Instead of taking the owner, the SCM source owner's context, I have, I've provided, I've asked it to ask for the context. So it is generalized. And then it would, so it would then go and look for the personnel. So if a person is entering a GitLab URL in the Git plugin, it would provide the credentials, a personal access token. And that token then can be accessed by the GitLab branch source plugin. And then that would be used to create an authenticated connection with the client API. And that's how, yes, yes, ma'am. So you said you'll use a personal access token, but doesn't that then preclude doing anything with a GitLab URL that uses SSH? Because in that case, it only has a private key credential. I mean, that's okay. It just, so this, this, the technique you were describing were great for HTTP based Git URLs, but not for SSH based URLs. Yes, it would not work for that, but then, but then what I want, I would see is that, so I look at how the current branch source plugins are taking the credentials. And if we look at the default credentials method to get the credentials for the GitLab branch source, they are asking for the personal access token only, not for, so what you're saying is if we have, so the SSH URL, we would have that if we have a personal server where we have a GitLab server hosted, right? And then we would want to connect to that server using SSH. Or in any case, we would have a server where we would establish a SSH connection and we would need a private key to do so. Okay, so. But it's perfectly okay that the SSH case needs special thought. That's perfectly fine. Solving the HTTPS case is already great. Yes, and why I did not think about it is that I, whenever I look at how this has to be done, I look at the current way the branch source plugin is handling credentials and that is why I just shadow the same process and I did not think about the SSH servers. But yes, that's definitely a case we would have to. Well, and there's no choice there because there isn't a way to do a REST API call with an SSH token, with an SSH private key. It just isn't, it can't be done. You'd have to find a way to translate the URL to HTTPS, but for custom URLs, you're kind of sunk. Right, exactly. Like you could maybe do it for gitlab.com. Well, like if it's mobilebubble.com. Right. What am I going to do? Okay. So now with this implementation, what has happened is that we can be sure that we need, if you talk about the Git plugin, we do not need to send any other information to the plugins. I was also looking at the Gitti Brand Source plugin. I haven't looked too much into it, but I, as much as I was looking at how they're authenticating the connection, it's the same process. They are also in the Brand Source, in the SCM Source class, they are trying to get the owner's context and then, and then it is trying to create a connection. So now my, so now we had two points to discuss. The first was what information we need to send to which plugins. So now the second decision to which plugins should we delegate this responsibility depends on, so do we want to implement a general method here? So the GitHub Brand Source plugin does implement a method where it is asking for the context. And, but it is perfectly fine for the Brand Source plugins to say that I don't want to ask for the context. I know that I am going to be, I am running in an SCM Source environment. So I would get the SCM Source owner's context and I would need that to provide the credentials. I do not need to provide a general method to get those credentials. So should we shift this implementation, the responsibility to the GitLab plugin so that the GitLab plugin won't be a plugin which would not be limited to a multi-brand project, right? It could have endpoints which could be accessed by other plugins and it does not have the sole responsibility of working for a multi-brand project. That is what I am saying. So programmatically or technically it doesn't matter to us if we are putting this implementation to the Brand Source plugin or to that plugin to the GitLab or GitHub plugin because one way or the other we would have both of them if the Brand Source plugin is installed we would have the other one but yes, the vice versa would not work. We could have the GitHub plugin but we would not have the GitHub Brand Source plugin but I am not personally aware of the use cases of the GitLab plugin and the GitLab plugin. So that's something maybe you could tell me there are use cases. So the decision rests on this fact that we could create a method which would just take the... We just need the Brand Source plugins to take our context and then look for the credentials because we will provide the credentials from our context because we would have the user who would choose the credentials and then only would access a private repository or GitLab repository or a GitHub function. So we need that from any plugin. So since the GitHub Brand Source plugin is already... it has that method and I exactly did the same for the GitLab. I haven't tested it because I'm having some issues I want to discuss later but it's the same... line by line the same thing we're doing for the GitLab Brand Source plugin and it should work. So the decision rests there. Should we move this implementation to those plugins or is it okay for us to keep this in the Brand Source plugin? So it would be only I think one case where we need to see is that... So for the Git plugin it doesn't matter if the plugin from where we are asking this information. So if a Brand Source plugin would have multiple repositories mapped to a single owner, Git plugin would, as far as I know, would have one owner, one repository. We're talking about a project. So that might... we might think that that might be something which might create an issue but since we are providing our own context and we know that the Brand Source plugin would take the credentials from our context we just need the functionality of that plugin to be able to connect with the client server, client APS. We need that. The credentials, the mechanism to scan the credentials is pretty much the same in the Git plugin or the GitHub Brand Source plugin or the GitLab Brand Source plugin. That's what I saw. The way it scans the credentials and the type of credential it looks depends on the Brand Source plugin but the way they are scanning for the credentials is the same. So for us, as far as I understand, it doesn't matter to us if it's implemented in a Brand Source plugin or down below to the GitHub plugin or the GitLab plugin. So, yes. So I think what we need is first definitely interactive testing because I have been facing some dependency issues because of which I was not able to upload the GitLab Brand Source plugin to the same Jenkins instance where the latest version of my Git plugin is installed. Before moving to that point, is there any concern, any doubt or anything we would want to discuss? I'm not concerned about whichever path you choose. So I think if it feels simpler and more elegant to you to do it one way versus the other, that way is great. The Git plugin for me is the closest to a clean room implementation and I think you said it does not contain this needed function. It doesn't have it. Yes. Just one second Mark. I have looked at the SCM Source class. Usually when I'm looking at a Brand Source plugin I always go at the SCM Source class and then that is the point where I understand how the client is being created, what it means and I do the same thing. Now I haven't looked at the other classes where the Git plugin might be using a credentials function where it's taking the context and doing that. I haven't looked at that. My observation is just limited to the Git SCM Source class. So which of the two alternatives would make it easier for you? Is it indifferent to you which way you go or is there one that, oh, this would be easier if I did it this way? If all the plugins look like GitHub, Brand Source, would that be easier or is it rather some other way? For me it doesn't make a difference till the point I... So it's different for each plugin. For example, for GitLab Brand Source it doesn't matter if it's the GitLab Brand Source or the GitLab plugin because the way I am creating the client I'm not using any wrapper method provided by the Brand Source plugin I'm using directly the Java implementation and instantiating the client like that. But when we talk about the GitHub Brand Source plugin they have provided a common utility class, a connector class where it takes the repository URL and it takes some information it takes the credentials and does all the work for us. So maybe it's for us, I am not sure if it matters if you're finding a standard common decision that if we implement this extension we are going to implement this extension at all Brand Source plugins only or if you're not doing that then we're doing it for the independent GitHub plugin on the GitLab and so on. Maybe we could look at cases for example in the GitHub Brand Source it's what I have already done it I have tested it inside my local instance with the credentials and private repository it is working, it's getting the size and as far as I'm concerned I think I need the size and I'm getting it so I'm not sure if it matters too much what plugin we are using. So maybe we need to look at that from the perspective of so it doesn't even matter if we have a multi-brand project or not because so that dependency is also is not there because these methods do not require the context of the Brand Source plugin it requires a context which we would provide so we just need a Git plugin, a pipeline which is trying to use Git as the SCM and then doing whatever it wants to so I think it would not matter to us if it's a Brand Source plugin or not What are you using the item context for? That is what I will show you exactly You thought that was used to pass the credentials in right? That's how you are relying on them to get the credentials for that job Yes, so the lookup credentials which is probably the credentials API it takes three things from us it takes the type of credentials we need, it takes the context and then it takes the URL you are providing and then we match it and you said the Brand Source plugin not the GitLab plugin is where your convenience method is I see here it's where you've written this one but did you say there was a pre-existing one or you're talking about this one online 751 751 is the pre-existing method which is provided in the GitLab Brand Source plugin how it takes the credentials so if we see it's getting the SCM owner context here instead of doing that I am providing it the context and I add this context here that's just what I've done and the rest of the way of looking at credentials it remains the same so this method can be static this can be static because it is not connected to any instance of the current class where it is in the SCM source class it doesn't matter if we are using a SCM source object or not but for this way of taking the credentials this is not static so we cannot use this method to pass down the credentials to the extension class extension implementation so what you're doing seems quite reasonable to me you're saying hey in the case of GitLab SCM Source I need to ask a question what is the personal access token associated with this context so that I can use it and ok now you indicated that you could choose to put this instead in the GitLab plugin was that yes we could do that because we need two things to implement these methods my extension and this method the credentials API and the GitLab API GitLab API so we would need those two things and we would have that inside the GitLab so we can implement the same thing but there isn't an obvious place in the GitLab plugin where this would naturally insert whereas the SCM source it's a natural location to insert it that's where the GitHub branch source has it GitHub branch source already provides this at this layer the GitHub branch source plugin has so it contains these scanning credentials inside the general connector class the utility class I was talking about and it borrows it in the SCM source or wherever it wants to that is how it is working yeah so the concept of a connector is at the branch source level in the GitHub branch source plugin that seems like a fair justification doing the same way following the same pattern putting it in the GitLab branch source and you're planning on using this when they set up the freestyle project or at runtime so when when it builds running it has to be at runtime because it's used for repository size calculation exactly yes because I think this use case is when people are setting up a branch source plugin I think this is used for jelly is it so I thought this was can would then be used oh I don't know okay I think the I think what happens is at runtime this is used to produce the output for the UI and then the user selects the credential they'd like to use it finds the candidates and then it presents the UI presents the credentials that the user can use the user selects the credential and then they save it and then inside of the config XML of the of each underlying job in a branch source set up you'll see a credentials ID stored and persistent so Justin is that is that are you are you considering them that should we store the credentials ID as part somehow as part of the the the question to ask for the size of a repository I'm not sure I'm understanding how would how would we use the the information you've shared yeah I guess I'm wondering if well I have a couple of questions about it one at runtime like are we potentially going to expose credentials we shouldn't if we detect the wrong credential the user doesn't want to expose which that's a hard problem from usability perspective I think that's hinting at the first question that you're asking is like are we going to make people select which credential credential they want for size calculation I think that's kind of your question right well the way Reshab has implemented it as far as I understood it it's the job has a repository defined for it and that repository has a credential associated and he's relying on the called on github when he calls into the github branch source it will using that job it will find the credential ID for that job and use it so so I don't think there's any leakage because the credential ID is absolutely associated with a specific job did I understand correctly but Reshab or correct me yes so so if if I am if I am creating a freestyle job and if I choose to check out the SCM using github via a github private repository so with the repository I would add credentials for that repository to do the process to do the thing to check out and that those credentials would be the personal access token in in case of GitLab those would be the personal access token type of credentials I'm choosing and then so I now the Git plugin would have the would connect these credentials with the repository user repository information we have and then we could send the credentials ID of the particular job and the context of the job to this extension which lives in the branch source plugin and then the branch source plugin would use the jobs context and the credentials ID we've provided to get us the credentials yes that's that's how I have I see so it's only scanning credentials associated directly with that freestyle project yes yes just okay I'm less than the freestyle project mode so that's where my questions are coming from to you probably so now I'm one question I'm wondering at is if this is this function of scanning credentials is independent it looks like it can be implemented anywhere because it just needs the context it needs the URL and then it needs the credentials but then okay we need the information for the client API client and that we can find only either in the branch source plugins or the GitLab plugin or the GitLab plugin never mind I was just so for me I need to the GitHub branch source plugin extension it's interactively tested it and confirm that it's working but with the GitLab one I have not been able to so if we don't have any question if there's no concern right now we would like to ask the question related to the dependency issue so in the Git plugin we depend on the Git plugin of course and so since the unsupported command is shipped in the latest release Mark I assume that the Git plugin would depend on the latest Git plugin plugin now not yet you'll have to explicitly declare that and you do that here by inserting a line version version yes right yeah so and the technique that's being used here is this particular file is using the Jenkins plugin bill of materials and the Jenkins plugin bill of materials provides a default Git client value that was verified and that default value is lower than the one you need so you'll need to declare the version number explicitly there then three months or six months from now when the bill of materials is updated we'll be able to remove the version declaration again okay sorry for the confusing nature of Maven management that's okay so currently in the pull request I did add the version it is without that my test would fail but now when I was trying to so the Git lab is directly depending on the Git plugin it has added it as a dependency in its form but the issue comes when I'm trying to so again having the Maven Enforcer plugin upper dependency issues while doing so and so what I did was I just excluded all of the dependencies which are creating those upper dependency issues I'm not sure if that's the right way to do it but wherever I was finding a conflict in versions I was just excluding them which the Git, the latest Git plugin would have different versions and what the Git lab Dancers plugin needs are different so it's different so that was creating an issue so I would expect that those I don't know that may need some further investigation because those exclusions I don't know I always have to work through very painfully these Maven Enforcer Enforcer issues so I'm a little surprised at those exclusions but does it run for you okay when you attempt to load this in a runtime I'm still having Enforcer issues I am having it for the Git time so if you never understand this line I always take it as a conflict and I try to exclude it I don't understand this line what does this mean I understand that we have two versions of the same plugin and that is why we need to remove one is this what this line means it says it requires upper bound dependencies for the Git client and it's creating the 3.2.1 version I am getting the 3.4.1 version the Git plugin has declared the 3.4.1 version so initially I thought since the Git lab branch source is depending on the Git plugin it would get the Git client plugin from the Git plugin itself so why would it create a conflict I could not understand something else is probably also declaring it well except the report here is actually saying that Git lab branch source depends on Git plugin 4.3.1-snapshot which depends on Git client 3.2.1 I would have interpreted that to mean that somehow your 4.3.1 snapshot is inadvertently declaring that it needs 3.2.1 that surprises me though because you said it doesn't even compile for you if you don't depend on 3.4 at least 3.4.0 right yes yes it will not compile okay I think I can look at the dependency tree and maybe I should look out my day like that that's how I so what I need to do right now is to add this run source instance in this plugin in my Jenkins instance and then I could test it for a Git lab report in a free site project so I I'll try to solve this and I think after that so again in the last meeting we had the conversation that the Git lab requires a server name instead of the URL and the run source plugin by default does not provide us a method to directly use the server URL to get the client but I was able to look at the Java API implementation there was a way and I implemented that in our extension so that's solved also I using curl request and so we also I I had an issue in the last meeting that the size of the repository comes under statistics for a project and you and in the documentation it said it said that we need particular access a user would need access to particular access to that project to get those statistics I was able to get these statistics so I have a Git lab repo for which I have developer access to so I'm assuming that it would work for us in general cases for anyone not just the owner I had the issue that it might only be able to get the statistics for the owner of the repository of the project that's not true so now as I need to implement first of all the current PR 931 now it has the unsupported command work all that I shifted from PR 937 to 931 so now in 931 the Git tool chooser is being instantiated in the Git HCM particularly in the method which is creating the client so if someone wants to run the plugin it should there should be they will be able to test the Git tool chooser with simple checking out the repository a freestyle job in any way what I need to do is I need to add other places where the client is being created as well particularly in the HCM source I haven't done that there so for me that's one commit I have to add and the second then would be once we have covered all the places where the Git tool chooser is being instantiated to add a similar safety switch in the global configuration page like we added for the redundant fetch issue so then the user would have the ability to not use the Git tool chooser so this is something I still have to do so these two things are missing from that PR but I think in terms of Git tool chooser it's the design and the function it should provide it is doing that then there's one more discussion which we haven't discussed related to what the Git tool chooser is returning currently it is returning a string which is the Git executable path which is directly to the builder of the client Justin and Fran have recommended they've said that we could instead of using passing a string if in case we're not able to recommend anything the Git tool chooser sends none and then I have to add another check after that if the recommendation is none then don't use the recommendation use what was provided by the system the Git plug-in the Git plug-ins recommendation instead of that we could use the Git tool so I do not understand the use case of doing so if let's just go where the Git tool chooser is being called and we'll see how the result is being used so this is the PR 931 code so the chooser is being called and the chooser's tool which is the executable string is then directly added here so if we return the Git tool Git tool instead of a string I think it's the same thing we would have to then get the executable from the Git tool it would store that I guess the only advantage where we use the Git tool is that for the cases where we're not recommending anything we would go to the default installation but then that would be a concern for us might be a concern for us because Git tool then would make another decision which we do not want to make if we're using the Git tool because we have to consider before changing what kind of implementation we can suggest we need to consider what the system and the user has selected so the Git tool chooser is now equipped to look at those decisions and then provide the result but if I instantiate a Git tool and I add the recommendation we want to give to the Git tool and then we return the Git tool in case we are not providing any implementation the Git tool would default installation that's right I think so yes and that would then that might be an issue for us because if you're not able to recommend an installation that doesn't mean that we should switch to the default installation we should use the installation with the Git plugin before the Git tool chooser is using the exact same implementation so that we do not break any possible new skills that's what I thought with returning Git tool instead of the string Fran and Justin why should we use Git tool do you think there's an upside using Git tool instead of returning a string I think some of the challenges I had with it is that we have none scattered about the code a little bit so instead of using that we could do something like using Git tool which is typed and then instead of having none you could potentially have a constant like there's a pattern called no object pattern and what you do is you have a kind of a dummy of that type that's that signifies that it's done in this case that you're representing if we need to have some kind of null then maybe you would do something like that you would have a constant like revert to default Git tool and and then you would use that to determine whether it should be the other one if you don't need that and you already have access to the default Git tool that was already selected then you have another advantage that you can just send that back potentially I don't recall if you're if at the end of the day we're sending back a Git tool anyways and that would be another reason why I would kind of maybe say that we should use a Git tool class if that's the case Does that kind of make sense? It does, Yasin. So if you're not talking let's just if you're ignoring the Git tool here if you're ignoring this part of the code the existing the Git plugin implementation we do not use the Git tool the Git tool the Git this function internally uses the Git tool but ultimately we provide the executable path string and then we directly add it to the client here the builder method for the client that is how it's done right now but what you're saying is I understand that so my only concern is would I have to update the Git tool class I was saying that I was just wondering if that's something we need to do if it's what's that change changing the Git tool class to add our case if we do not want to recommend anything we add a constant Why would you change the Git tool class? Maybe I am misunderstanding what you said so the case I am talking about is if I do not want to recommend anything the Git tool doesn't as far as I know it looks for a class either a descriptor so if it doesn't have that if it's null if we do not provide it it defaults to the default installation which is inside the plugin now with that my concern is that then we are making another decision without considering what the user and before reaching to this point the plugin has made maybe what I can do is that I could possibly I haven't looked at I can try instantiating the Git tool and then looking at how this could be done and maybe then we could have a better discussion about how we could use the Git tool or should we use the Git tool or we should provide a solution I don't think you would need to change the Git tool class you would just instantiate if you needed to use the null object pattern I don't know if I am not super convinced but if you were needing to do something like that and I think that's kind of where your concern is about changing the Git tool class you would probably just create that constant I think you only care about that here and so if you only care about that here it seems like that constant could live here and get SCM and you would use that to make your decision of whether you're going to go back to the system default and you're going with this friend when you said you wanted the executable from the Git tool yeah and then you would just use the executable from the Git tool yes and I think that seems like the better way to do it I only did not do it because we were making some custom decision which the Git tool is not good to make but then I think I should look at the Git tool class first I haven't I do one thing we can discuss this on Friday I can look at the Git tool class and how we could if they're not providing any installation then how we could use the Git tool and then give that message to the Git plugin I think that could be a better way to do this then I think so another thing I need to do is after doing all of this I need to calculate the time spent on the jobs without the Git tool chooser so that after adding the Git tool chooser we can compare jobs and approximately reach to a conclusion this is how this performance improvement is worked we need some metrics for that those metrics will come from this experiment so I have enabled the time I think it's called, I'm not sure what the plugin is called but it just timestamps the build console logs and I think I would so what I'm wondering is what kind of use case, so what I was assuming was I was taking the lazy path of just using Mark's instance and not worrying about what kind of jobs I want to test here from which jobs I needed I was thinking that to get real metrics or close to that point I need to measure jobs which are used in production and some what something like that because if I do the same thing with my instance what I would do is I would look at a brand source maybe I would create a multi-branch project with varying sizes of repository I could do that and I could then see how the plugin is the performance is changing in the checkout step how it's changing in the scanning process so there are two ways to do it my approach, my default approach was to just install the plugin not first expect from where the performance improvement is going to come and look at jobs with huge workloads multiple jobs with Mark's instance contain and then see the difference after I think they get to choose it but I'm not sure if that's the right way to do it or if it's possible because to see considerable difference we also need to vary sizes of repository I was assuming that one of the project would have Jenkins IO but I could not see that mark in the instance so what I'm asking here is what approach should I take where I know the first area where we could see some improvement is the checkout phase so I should create five projects with varying sizes of repository and then measure them profile them with my JFR in my local instance and then I can say that this is the difference in time after the get to choose it has been added and then I could move on to the areas of the plugin for an example the SM source the scanning of repositories and then building those repositories I could look at those areas and then measure the differences like that so I mean yes I'm not understanding what you gain by using JFR on your local copy that time stamping when I enable it it looks like it does report it at least to per second resolution and so it does provide second one second resolution let me do a quick check just to see if I change to the JGIT implementation does it still time stamp but I think it does at least well enough to see it so I don't know that you need to use JFR locally on your environment you're welcome to create those varying size repository or varying size jobs on the test environment or your local either is fine wherever it helps you get the data that you want that you need okay so the question of like how you can do the slicing of before and after maybe I didn't understand the overall question I guess the overall question is how should I how should I get the metrics to understand what kind of differences this class has made to the GIT that's the aim of this experiment and I would use that in the final presentations and reports that's what I'm trying to figure out I was actually thinking out loud when I was giving two approaches of doing it so I guess I would default to using I would create different projects with different size of repositories and I would like to do it on max instead of my local instance because I I've seen sometimes at my instance because of because of my personal resource it the reports are sometimes it's too varying reports of different builds for the same repository for the same configuration the profiling which I do from profiling I've seen that the local instance my local instance adds a lot of variance to those results and I think if we are providing these results might be important for us because they kind of signify what this project did to the GIT plugin so the results should at least we should have some confidence in those results whatever however smaller increase will be added to the percentage in performance improvement or larger the change doesn't matter but it matters the results we have consolidated results one more thing you might do as you're establishing those jobs is intentionally declare them to only execute on agents with the label cloud that way you're avoiding the wide variability that exists in the hardware that's behind on my Jenkins instance all the agents that are cloud instances are allocated on Google Cloud platform they're the same basic processor type you'll get different operating systems but they are the same fundamental processor type and so you'll get on average a more common throughput result than if accidentally you run on my ancient Raspberry Pi as opposed to a thoroughly modern new computer running Debian testing or something like that or your bitcoin miner right or my bitcoin miner that's right why didn't I think of that because that's something I want to do with my electricity is mine bitcoin of course I have an entire rack of bitcoin miners and they've all got GPUs enough enough diversion that's great go ahead Richelle yes so okay I'm going to do that okay projects and that's how I'm going to get the metrics so from my side I think I've explained what I have to do from the mentors we need the GPU chooser to be reviewed and then I think much I don't see any blocker in that process if you come out in the review process I hope I haven't left out anything Justin Fran any comments in the PR which although I made sure that I did include each of the suggestions only one thing was left that was Justin and Fran's recommendation of using the get tool instead of the string that's something we've left but it's apart from that I think we've included everything in that PR if still there's something I would have to have that review I think that's it so on Friday I would I would try to in so I would should be done by instantiation and and adding the safety check I'll try to set up the projects and if we're able to see some results we'll discuss that if that's possible so that's it I think last time we discussed the point like for the GitLab you needed the owners permission level so I think you missed that point so so I tried to clarify the doubt I had at that time I tried so I used actually I have I have developer access to a project a private project in GitLab so I was able to get the size so there are varying levels of access provided to roles in GitLab so they range from owner to reporter and I have developers access and I was able to get the size so maybe I misread the documentation and that is why I was saying that we need the owners owners rights to get the size statistics yes yes yes you basically just need read access to the repo any role that has read access should be able to see the statistics yes that's perfect that's what we need so thank you for spending more than half it was just a 30 it's a 55 more I'm sorry for taking more time than we were scheduled to