 Welcome to Jenkins documentation office hours. It's the 24th of March 2022 agenda topics. We've got news using crowd in enterprise for localization Linux installer switch from system five in it to system D she code Africa and open PRs as possible. We're going to plan for a demonstration and do it live today on crowd in enterprise thanks to Alex for being here. Any other agenda topics we need to put on the list before we before we begin going through the agenda. All right, then let's do it. So first welcome Kevin Martins. Kevin is a new documentation contributor we're delighted to have him with us Kevin, give us a two or three sentence introduction of yourself. Yeah, I'm from Boston mass I've been writing since I can remember and have a background in communications and support. And I'm really excited to just be part of the project and start contributing to the docs. Thanks Kevin, welcome. Grateful, great to have you here. So next topic, we're going to have Alex take me through a tour of enabling crowd in enterprise on the Jenkins platform label of plugin. So, two weeks ago, Alex showed us a demonstration of how to do how easy it is to manage translations using crowd in enterprise for open source projects. So Alex, let's go ahead and you coach me on where to go and what to do. Yeah, the domain is intellectual sites. Intellectual sites that crowd and calm. Okay, intellectual sites that crowd in. Okay, like that. That is perfectly fine. Then you had to sign up the center upper right corner. And I can just use my GitHub credentials. Okay, and it's only accessing public data so that's perfectly healthy. Okay. All right. Okay, now I log in and it will probably ask me how and I log in with GitHub. I want to know who I am of course. Great. And yes, I accept the terms and conditions. Okay. And it's okay that I used a Gmail account. I didn't have to use a, yeah. Okay, so verify email. You don't need to do that now. Okay, because we have no password because it's provided by GitHub. Right. Okay. Quick. Yeah, Mark, wait, right here. Okay, refresh the page. All right, so refresh the page. And in the intervening time I've also verified my email. Now, what was quick. If you had to console. Okay, go to console. Yeah, you click on create create over here on the right. Yeah. And let's name a platform level of login. And does it need to be, can I use spaces, etc. It's just a name. It's not the URL or ad. Okay, so I certainly can. All right. And I want to go to languages. You're part of Italian. So I want Italian. You can pre fill and click the 30 most selected languages. Oh, wait a sec. You say there's pre fill here. Yeah. You can put up 30 selected languages. You can put them automatically and then I can clear the ones. Okay, I don't expect a Africans catalog. I'm just using that as mostly a sample. Right. Okay, so Danish, Dutch, no, no French yes German yes Greek no Hebrew no not yet Italian Japanese possibly Brazilian Portuguese might happen. Russian, I might persuade somebody to do. Okay, Spanish, I know I can Swedish. All right, good. Okay, so now I've got, I've got 10 languages is 10 too many is it's 10 okay that I choose 10. That's fine. Let's crawl down a bit and select crowdsourcing on the workflow crowdsourcing that basically means that everyone can sign up on this instance and provide translations. Okay, great project. All right. Yeah, below at the screen you get a little tutorial because you signed up on it initially. Okay, so this is saying, Hey, there are integrations I could use and one of those integrations I assume is GitHub. Yes. Okay, and so and I could also invite people. Okay, and set up to you to invite individual volunteer translators. Okay, got it. If you want to integrate your GitHub project to click on project settings in the bottom left corner. Okay, so project settings. Let me pick your project level up again. And I probably meant integrations. Oh, oh, okay, all right, so it's above project settings button you just scroll down. I see okay so so if I scroll down integrations. Got it. Okay. I'm going to pick GitHub. GitHub. Okay. Oh, and I probably needed to pick the connect but all right set up integration. Yeah. You don't choose a personal access token here because it relies on the off graph. Okay, so, so it's, it's saying that it wants organization or it will get organization access to Jenkins CI. Yeah, is that is that safe in this oh it's home but only only it just needs to know where to get the data from. Okay, so it's not this isn't, and this is only public information so it's not going to get access to private repositories if there were any. It's really public information from Jenkins CI, but access read and write data from your account, like to your repository. All right, so this this application will be read and modify repository web hooks. Okay, no direct code access, and it will have access to read and write public and private repository data, including okay so. Yeah, that's needed to to publish a translation some crowd and to get up. Okay, all right so I think this is safe then let's go ahead, authorize. Oops, now I've got to pull out my security key to factor authentication is my friend it'll be just a minute while I do that, hang on. I love my Yubi key really truly. Yeah, my mind is saying just the best way to do two factor authentication okay use security key. And it now says, Oh, that was easy much faster than usually I get two or three failures. Okay, great. So that's your, your account. And if it's done you see your avatar on the gray box and you can select your repository on the drop down. Okay, and I assume it's querying 1800 or as many as 2000 repositories here in the Jenkins CI org so this is going to be a while isn't it. No, no it queries the data from your account it's not it's we didn't install crowded on Jenkins just accessing your account. Okay. Yeah. All right well so so then. But this is just one way to integrate it you don't necessarily need to do that you can also use a GitHub workflow to push and pull things for example, but I think we are going to do this today, because this is how you would do it through a crowd and. Okay, so, so it's going to eventually finish querying the list of repositories from my account. All right and now I select and it will be. You can also type and platform. Yeah, so I use Jenkins CI says platform. There it is. Okay, yeah, branches for translation we'd like the master branch. Yeah. And this is okay as a name. Yeah, that's the name with branch name it creates where it pushes the changes to. Okay. All right, well down. We can say, this is fine. We send them every hour. I think platform level it doesn't have much traffic for new contributions so this is also also fine if you click save. Okay, go out. And now help me on this. Sorry, before we go, the duplicate strings is this a something that should matter to me I'm used to thinking that in Java duplicate strings are always translated this in the as the same string. Yeah, I'll do because it's fine here. Oh default is fine. Okay, good. All right. Okay, save then. Now we've integrated the repository and now we set up the branch where the language files are on. If you click on the three menu dots right next to the exclamation mark. No, the one below. Oh below right there. Okay, and we click on branch configuration. Okay. I'm Alice the file that is going to be pushed to your default branch on GitHub in the next run. Okay, so I'm going to press continue here and this is a file they will place there that configures crowd in for my repository. Yes. Okay, and so I have this where the repository where the translation drinks are coming from and the translated files path is where they are going to. So the source files path would be like I think source main resources and so on. Okay, so if I do source main resources, you can work with us the risks here to include the nested folders and relative pass source slash main slash resources. And is it ant style pattern match or over the question mark in the circle, you can see what is supported. Oh good okay wild card selectors. Oh good okay so like something like that should get anything in the resources. Yeah, and now I don't know if this plugin has had been had any setup for for properties at all so we I may be it may be completely infeasible well it's I guess it's got jelly files and those should be translatable, but we'll know we need property files right we need something that will guide the files but you also have HTML files that would turn. Oh, right, right. Okay, and those are like something I saw. Perfect. Yeah, but I would add asterisks dot HTML to exclude the jelly files. Okay because jelly in this case is not a translatable thing we would want. Okay, so that's that gives me one now. What if I need to put property files as well. Whoops. That would be the properties for properties. And so do I add that as a separate line here. I think you can have several strings and several paths that I'm not sure how to do at the moment. Okay, alright well so let's know HTML files can be translated so let's translate one of those. Yeah. Hopefully you can copy the source parts and put it into the bottom one, remove the last part, the asterisk dot HTML. Okay, if you hover over the question mark. Ah, good. These are the supported placeholders how you can name the file. Ah, good. Okay, so it would be something like original file name. Yeah. No, well no is that is that with or without the suffix. That's only the original file name, but we want original file name. And then the underscore underscore and then we want the to lead to care to letter code. Yeah, to let us code. Okay, alright. We can use dot HTML. Yeah, we can use dot HTML or to work with the placeholders. I think it's file extension or what was the name. Oh, yes, you're right. There is a file extension. I saw that. Okay, it's this way by doing this that this single translated path would then work for properties as well. Yes. Okay. Alright. Okay, and now we can save the changes. Okay, and now how do I get the save to be active? We first need to click save the safe changes at the bot at the top. Oh, at the top. Got it. Okay. Yeah, there we can save it. Alright. Okay, now you can hit the sync now button. And if I hit sync now. Yeah, so it's now. If you hover over the progress bar it tells you what's going on. Okay, so upload source files so they read our read my repository. They're now going to download with their working area. Download translations process web hooks. So they've hooked in web hooks into my into the Jenkins CI platform label or plug in. And now they're actually doing an initial translation. They're just setting up the default branches and the current file. Because if you head back to get up and take the platform label up like and you will see that mark weight committed this file a few seconds ago, but it was processed through get up. Okay, so let's let's go see that so what I should see is if I look at the commits here is update the crowd in configuration file, and there it is. So this is what we just created through the web interface. Like we can see it's also possible to do it through GitHub and modify the file here. Yeah, if you have if you had back to crowded. Okay, click on project crowdsource translations crowdsource. You say translations crowdsource. I'm okay. How am I missing this roughly where it's on the left translations. Okay crowdsource here we go. Okay. Yeah, we need to publish the project source available on our instance. Okay, but before we do that I want to give. Oh go ahead. Yeah, if you don't do that the project remains private and only you and me can access it. And if you click the publish button, it's available to everyone on my instance. Okay, so I think I've got an oh no I don't have an icon for this one. Okay so no icon I can't. I was going to give it a better logo for the get plug and I have a better logo so okay so I just press publish. Yeah. And if you just had to intellectual sites on crowded calm. It does appear there. Okay so now if I open up intellectual sites crowded calm. Yeah, that's our platform label plugin there it is okay with a with a terrible logo. Okay so it needs a much better logo. Okay, and if we if we click on it. We can see the languages you just set up. All right and so I can see the English language for instance and yes here is a. This initial tutorial everyone has shown to. Okay that's. Before I would translate something I would head back to the project configuration page. Okay, these are the three menu dots. Right here. Yeah project settings. Okay. Because you want to configure it to only export strings that are approved and translated. Otherwise we get the pre translated files with the English default on GitHub. I think we don't want that. So we had to project settings that's on the project settings. Okay, so project settings. Yeah, we scroll down a bit further to the box. Yeah. And we say export strings with at least one translation. That is fine. Okay, export translations with a specific number of approvals. Ah, okay now we have approved strings on GitHub. So tell me again what is an approval when in this case. That would equal get that would equal pull request approval on GitHub. Basically, who reads over something and says that's fine we can use this. We want to skip on translated files. Skip on translated string or script on translated files and that's it. Oh, okay. All right. So only files that files that have an approved string land on GitHub. So we, so we don't need to look over it on GitHub again. Okay, and if we save it. Save it. Okay. I think we need to head to your repository first and clean the pull request, because we didn't configure the previously. Oh, okay, so if we go to to here there will probably be some there is a pull request new crowd in updates and what we see here is what you warned about it is that it's proposing the English text in the German file, for example. Yeah, this is what we didn't configure. That's why you should configure that first before we do anything further. But you can also prevent this. If you don't start the cross then translation work for immediate immediately and started later on, if you set up a project. Okay, so I could have avoided this by just using a different sequence sequence of steps could you say that those that sequence again. So if you have a project that you can head back to the overview if you want. Okay, so if I go back to. Now let's see go all the way back to to here workspace. Yeah, and if you click on create. Okay. You can just click on delay workflow start. Ah, if I had enabled this, then. Okay, then I wouldn't have received that pull request. Yes. Okay, this is what I didn't mention yet but you can basically pause them to prevent that. Now, I will just close the, I will just close the pull request and delete the branch to avoid possible conflicts because we don't need it and can't use it. Okay, so, so in this case, and that's not a problem so I'm going to request changes. Oops, to counter that because you opened it. Right of course I'm just going to close it. Okay. I use I'm used to working with depend about where I just close every close it if or ask depend about to close it or closing because I don't want local language. English, copied to the local language file. We got that. Okay, close with comment. And now you said that I need to also delete the branch that it created just to avoid potential problems. Yeah. Okay, and now it's been a while it will always create a new branch. Okay, I'm used to using the command line to delete a branch. Any pointers on how I delete a branch from the GUI or if not I'm going to bring up my command requests tap. Okay. Oh, and just delete it from inside the closed pull request very good idea. Why didn't I think of that. Okay. Good, it's right here delete branch. Done. Thank you. Yeah. And now we can head back to current and basically start translating things from a translator's few. Okay, so now we go back to the crowd in where in this view or in this view is not available to everyone this is just a manager of you. Okay, default, the default views available on the default URL. Okay, so it's outside sort of crowded calm. So if I go if I take this URL start up a new tab and go here. Yeah, yeah, our platform label up like in. Okay, and now if I just click translate. Yes. You could basically select any language. You want to contribute to. Okay, so I am going to contribute a translation in Italian. Okay. Below you can see the machine translation examples. My Italian is not much good but you could. Can you verify that one of them is actually appropriate. They are all better than I would do so. Okay, general. I'm not sure what I'm not sure if that's the word that Jenkins uses for for. There we go I like to send system or operative or better. Okay, so I click the use and save to choose to use that one. And that's basically it. Okay, and, and that now has, I've, I've now started a session and I can do do more of those so let's say I'm going to do several of them I can do another one that says this looks like this, similarly useful. Jen, okay. Okay, so the, if you click on. Yeah, that's basically how you can translate things of course you can also put in something on your own. The machine translation is just the recommendation on what the things is the appropriate term. They often fit well but sometimes you have strings. It doesn't know what. Right, so, so well and these may be terribly flawed because I'm not a native Italian speaker right so so I embraced the fact that I may in fact be making a horrible to okay where did why where is this demo but at Tivo there we go. Okay. Yeah, I mean I can't verify whether they are somewhat appropriate. But if you say they fit then I think they fit. Well, and we've got a good sample here so okay so we've I've now acted as though I were a native Italian speaker which I am not. And, and now do I have to do something to submit this as a poll request. No for translator few not but US plug and maintainer can click on crowdsourcing. Okay, so as a plug in maintainer Italian all strings crowdsourcing. Okay, so crowdsourcing was here. No, no, I mean to the editor. Oh, from the editor okay. Yeah, there you have the crowdsourcing tab okay. Now we can switch to proof reading. Ah, all right. Okay, so now this is this is I've now switched from translation contributor mode into I'm the recipient of it. Yes, is that right. Yes. Okay, all right so and it's giving me a nice tutorial I'm going to put the tutorial away because you're going to give me the similar. Okay. Yeah, and now you can basically if you what you just translated on the left you can see the origin string and on the right you have your translation for it. And if you think that some of the translations are appropriate you can click the tick next to them. Okay, so I check this to say yes that's appropriate. That's appropriate and also approve them in batches. I could do this to select them all. Okay, yeah. All right. And if you click the tick in the upper left corner next to the select all, you approve them all. Yeah, approve selected strings. So this has taken me as a maintainer. I've been able to review the strings and now I've got. I've got those. Will it now submit the pull request and merge it, or how does what's the next step. I mean it will process pull request but it won't merge them automatically. I mean, it could you could configure it like that, but you always want to look over things again. Okay. All right so I've, I've submitted now I don't see a pull request yet so is it that it batches them or is there something I need to do. I think we set up the sync out to one hour initially. So one hour from now it will submit a pull request. Otherwise we would get up right limitation quite fast if every string would be a no pull request to your account. Yeah. Excellent. Okay, so, so I have. Now, can you guide me how would I invite others let's say you because you actually are a German native speaker. How would I invite you to or or Germans in general to contribute to this. Yeah, let's close the editor first. Yeah, you're already in the right point. Okay, so with clothes. Quit. I'm not. Okay quit on the left side, the three dots at three bulk things. This. Oh, quit. Okay, close the top. Yeah, like you can see on the left side there's a members tab. Members is right there. Okay. Yeah, I'm already invited because I own this instance but this way you could invite others. Okay, so, so if for instance, I'm going to do this. We're going to assume Kevin speaks an interesting language. And so I'm going to invite Kevin. Okay, so I've provided an email. And now do I want to give him access to all languages translation and workflow steps, for example, but you can also opt that out. And attempt to select languages. Okay, this is where I asked Kevin Kevin or any do you actually speak any of these languages. So, at this point in time, I'm going to go with just English my French is conversational at best. Okay, so French English it is great. So, so I can invite Kevin to English. Excellent. Okay, good. And now he's pending as proof reader like you can see is proof reader for this project. You're the owner of this project. And the other people you can see others other organization administrators on my instance. Excellent. Okay, so, so when Kevin accepts that invitation, he'll be able to proof read English language messages English language help. He'll be able to use HTML files. And when I add property files he'll be able to to also proof read English language property files with their English message. Yes, and if he accepts those strings they will land as a pull request for you on GitHub. Okay, no, if I when I add a property file, it will, it will be in English initially. So, does it allow him to modify them as well. So, source string. Yeah, but we would need to change our file detection first because we just configured HTML files initially. Oh, all right, right. Okay. All right. So just HTML properties files us and plugins often so that would be the two main things you need to opt in. But if he, but if you remember you can also use rejxp to define a clause. So you can easily spin something up as copy paste example for HTML and properties. Great. Okay, so Kevin's ready to review. I do have permission to. So, would you be willing to do a German translation of one or two strings here so that we could watch that, so that I could see that arriving in an hour or so as well. Yeah, for sure. So, is it okay if I stop sharing my screen and we have you share to show how that works. Yeah, I could do that. Okay. Yeah, platform label plugin and the screen. Yeah, that's the platform label plugin German. And like here we can have the here we can see the file tree of all those files again I want to continue to help architecture. Yeah, this is like the string of the file, generate label with us architecture. I would go with this one that fits the clothes. Yeah, that fits quite well. I can save this right away. And that's already all translations in this file. We could go on to the next file. Let's go with this one. Okay, no, and I see the highlights that's indicating changes from previous strings and oh it's saying that that's 77% match. Okay. Yeah, that is how crawling thinks that it's appropriate. Like a term like AMD 64 you want to is those are like, not the common words crowd knows about because that is not something you use in a typical sentence. But if we think have what if we have more, more projects on Jenkins and it learns from that, it would be able to pick them up and generate useful sentences. If you're relying on the machine translation crowd knows about, but it basically learns from projects, you can opt into. And if you have more projects on this instance, it would be likely be aware what these means. I'm proud and have a way to do some form of translation dictionary so that all Jenkins usages of, for instance in here in the German language label looks like a standard German word. But I assume there may be other words in German that could mean label that would be synonymous with it. And label as this word doesn't exist in the German languages just picked it up because it understood it from the context. Oh, okay, so that is not that's not strictly a German word. No. Okay, I think the machine translation, I think would be a hard time with terms like agents or branches or something like that. It doesn't know about yet. Right. And, and those are those are what I call high highly or high frequency terms. The concept of an agent or a node or a controller are probably words that have very specific translations in in Jenkins world into into English or into German but the trend they may not know what those words are. Yeah. Okay, I just switched to just switched with you know we are translation memories. Oh, okay, accessing all projects. This instance house. We are currently only using the translation managers from the plug in itself, but I could opt in all dictionaries and use words or string some different projects. Okay, so so conceptually, I could opt in to use the get plug in there or the Jenkins integration demos and think okay those might have might use related words in their translation memory. Yeah, for example. Okay. I mean I could not all things and use the words from all different projects, but certain projects as I've had different vocabulary and use different terms. So it wouldn't be quite appropriate here. But yeah, we can basically opt in the demo from a couple of weeks ago. And if there are matches to the words in here, like we can see. And this is what you translated this my translation, and this is the source files. And this is how it generates the machine translation and learn some of these strings in the context. It's just, it's not a plain dictionary that translates words by word, but mobile context. Back to the platform label up plug in. Let's say help. Name. Yeah, the translation didn't didn't change much because the other project just had about 80 words or something that's not a lot to learn from. But that's basically the concept how it works. Like the more people the more projects contribute to one instance, the less translators have to translate for other plugins. Right. And that's, I think what you just described is the power of a translation memory right it. Yes, it remembers commonly use words and will apply them with some some good guesses. Yeah. Like if you have the word agent and translated a few times like 50 or 60 times it definitely knows how to treat it how the context belongs and, and so on. Like if you have a few projects here with a few similar strings, it creates its own dictionary of Jenkins specific knowledge. Now, is there a way that I could, for instance, load Jenkins core as a read only source of translation memory, or is that that not not viable here. I mean, that it learns from translations. It learns from the input. So basically the source string is this one and based on your decision of the answer here. It learns what is the most appropriate term. So it wouldn't read for instance any existing German language translations in Jenkins core and assume that those were done by a human. It would be possible. But on the other hand, you would need to verify all individual things if they actually still fit, because there's still lots of legacy terms in core. I'm not quite up to date anymore. So okay so an example there would be, there may be the German translation of the word master in Jenkins core translation that should be converted to the German word for controller. Yeah. I got it. Okay, thank you. Alright so so better to treat this as I'm starting fresh. And from this fresh start we're going to, we're going to use the translations that arrive and that will give us better and better words to use in the translation memory. Okay. Yeah, I think integrating called the bigger task because it does offer the size and amount of files it has. And some of the files are let's say quite dated. Not more up to date so if you basically import anything here. Be like we could end up with wrong translations or wrong translation memories, which could have a bad influence on other plugins of other plugin offers decide to use code translation memories. Right. Okay, and I think that makes sense. It is in this case, particularly for the scope of this experiment, much better that we don't risk tainting it with anything other than new translations. Yeah. Okay. What, what else would you like to show thanks so much for doing this Alex so I've already I'm already going to within the next 60 or 90 minutes have a poll request that includes two German language translations and several Italian language translations with now a facility that others could contribute translations if they'd like. Yeah, for example. That's great. But just to note, this is just one way how to integrate crowd in because you went through the GitHub integration, but the same as possible through a GitHub action provided by crowd in. For example, if you have multiple contributors or for core where you don't want to bind the integration of one single person, because it uses your old scope for that. Okay, now that I'm not. I'm not sure I understood what you were describing so you're saying that that I could have done it something other than having an integration through this, this very comfortable web UI there's another way to do it through GitHub actions. Yeah, you can basically do the same with GitHub actions and a personal access token from crowd in. For example, to use it in core and provide translations as GitHub actions user and not as mark weight. Oh, I see. Okay, and that's, I'm delighted that it's coming in as mark weight because I made the choice as which text I'm should be using right so okay good. Yeah, the point is basically if you have a plugin with multiple contributors, and you don't want to bind the integration of one single user you can use the GitHub action and the GitHub action then provides the fight as GitHub user, one of the maintainers can merge later on. I see. Okay. Excellent. Anything else you'd like to highlight here in terms of nice features things that things that we should encourage. We've I've seen how I can invite others, so I invited Kevin. I could do the similar thing with with friends who are native French speakers, and, and they would be able to then do the same thing. Yeah, for example, but to make it easier, you can also create groups of groups of people and teams, you can invite on. I think that's, yeah, I think that's machine translation reports. Create a group. I think was that. Yeah, you can also basically create a group of people. Like if you have several contributors based similar to groups on GitHub. You can create a group of people you add to a project as reviewer proofreader or translator. Okay, so I could conceptually have a German speakers group for people who are native German speakers willing to help with Jenkins translation so German, German users of Jenkins could be in that that group. Yeah, for example. Okay, and that group would be above all other projects, you can basically add to. Thank you. That that's this looks great so I can go ahead and invite others and anything else that we should see. I think that's basically much so far from the point of the user. I mean there are a lot of more settings and things you can go through but I don't think they are much interesting because they don't show stuff you need to configure anymore. Brilliant. Thanks very much Alex thank you for thank you for taking us through the tour thank you for taking me through it and thanks for what you've already contributed to the platform labeler. Yeah, a problem. All right, I think, I think, should we call that topic settled for now. Yeah, I think so. All right. So if you're willing to join us again in a week Alex we do one more round of this to see what that pull request how that pull request came in. So what the experience was and I think what I'd like to do is see if I can deliver a release of the plugin that includes the translation so we can see that the translations really reached all the way to the user. Yeah, for sure. All right. Okay then we and we've we've we're at 45 minutes in we generally limit this session to 30. Are there any topics that we need to that we need to cover from our other notes so this one for me was most crucial. I'm less worried about these others you know this was not joined us and then had to drop off. So she called Africa and nothing to talk to there. And open PR as we do only as time allows so I think we're set with our agenda, any other topics I missed that we should should have discussed and didn't. All right then I'm going to go ahead and let's let's call this session done for today recording should be posted in 24 to 48 hours. Alex thanks very much for what you've done for us, looking forward to working with crowd in and getting localized plugins. Here. Thank you very much Alex appreciate it. Thanks everybody.