 We'll fix this on the fly down. Hello, everyone. Welcome back to another OpenShift Commons briefing. And today we have another in our GitHub series. So today we'll be talking about GitHub workflows and we're here with Ryan Cook. Ryan is out of our Emergent Technologies team in the Office of CTO at Red Hat. And myself, I'm Karina Angel. I'm one of the OpenShift product managers. And so GitHub is very important to OpenShift. And we're really excited to have you here, Ryan. Would you like to give a brief introduction and dive right in? Yeah. So Ryan Cook, I've been with Red Hat for seven years now and done various automation along the way. I stumbled into GitHub Actions thanks to a project called Scribe, which you also saw on OpenShift Commons a few months ago. So I kind of wanted to tell that story just to hopefully get people excited about it and kind of get them started. So with that, Karina, if it's up to you, I'll go with you. I'm going to go ahead and kick off. Yes, please. Thank you. All right. So the topic we're going to talk about is running my actions introduction to GitHub workflows. So to start things off, like I said, I'm a principal emerging technology developer, gluer of things together. So as you see with the infinity gauntlet of sauce here, products come into Red Hat or they're kind of found by various groups. And what kind of my role is to try to figure out what enhancements need to be done to let them run an OpenShift? Or are they a good fit to be merged with Rackam as an offering to customers and just try to put all of those things together to make an experience that a customer would enjoy? We do work on a lot of things that are about six to eight months out. So, but this is just something that we discovered along the way that's been incredibly helpful in speeding us up in our development pipelines. So what actually are GitHub actions? The easiest, simplest way to kind of dumb it down is to make it presentable. The fact that you can provide GitHub a series of workflows, series of steps to do and kind of an end result. So I can have GitHub manipulate my code. I can have it build an image for me. I can have it push the image to a registry. I can have it build a binary, save the binary, give the binary to someone else. And then it's just like it's unimaginable what you can do. You can actually have dynamic runners that come up and build like a REL7 instance and then test against it. The possibilities are endless. And so just to bring it back a couple steps, here is one of our projects. Simple. There was a push on the main branch, which triggers a build and a deploy. If you break down like to the simplest steps, this is exactly what it's all about. And GitHub provides this. And what we're going to kind of show today is we're going to start with just an empty project. And we're going to add a go file to it. We're going to create a binary and we're actually going to test it. And then from there, we'll do some PRs against it. And then we're going to move into like an open shift space, or we're going to build an image, push it to Kway, and then deploy it on that open shift environment. So this is our kind of simple diagram, but you'll see it again later because that's what actually we're going to use for open shift. So why GitHub actions? I think the nice thing that GitHub has really done in regards to first starting off with the ability to anybody in the world have access to a repository to store code, share code, collaborate with others. They have definitely lowered the barrier entry in regards to testing of your application code, verifying that it works or deploying it to an environment and verifying it works in an environment. And they provide the infrastructure to do this in regards to the Git repository hosting itself, as well as some runners and kind of workflow action computers that they provide to you, free of no charge. So this is just such a beautiful thing because you think about these startup projects or these college projects or countries where computers and technology aren't as, there's not a ton of stuff laying around like we have today. And it gives them the ability to create these projects, build mature workflows that can get the engagement with others. And it's just, it's such a nice thing. So what we're going to do is we're going to cover some key concepts. There's the concept of the runner. The runner is actually just the computer that is going to perform the series of steps that you define. And those series of steps are called actions. And the actions are just a set of workflows. It's kind of like do these steps and then do these steps and then do these steps. Following up with that, there are integrations. These integrations can be things that are found in the marketplace, such as a plugin called Mergeify, which if you get a plus one in your code, it will automatically merge your code into master. Or there's also things in the marketplace that we'll actually show later, provided by various companies such as Red Hat, a series of actions that you can just automatically press the button. It goes straight into your code and can provide a lot of functionality where you don't have to actually code all of these things. So the integration in marketplace will do a lot of the hard work for you. And then finally, the gate repository. I know that everyone is probably asking why is gate repository on the list. It's probably a key concept we already know. With the idea of actions and everything around actions, there are a lot of extra pieces that you don't really get to see or that you possibly haven't seen if you've just been using GitHub for repository-based things. And runners. And like I said, these are the computers that actually run your code for you and run the tests that you decide to make. There's kind of two sets of runners that you can do. You can run these hosted within your environment. And GitHub actually provides a binary for you to run in your systems. If you're running OpenShift, there is actually, and I believe it's in the Red Hat marketplace within GitHub, there is actually a plugin to allow you to deploy this into your environment via help chart. And gives you the ability to run these runners within your OpenShift environment. So using that compute that's on site that has access to your internal resources and meets your kind of security standards that your company has currently set up. It's kind of cool because it's your computers, your constraints, your security team, and GitHub is just saying like just execute it now whenever that trigger happens. And then lastly, there's greater control of reversioning. And I bring that up because a few weeks ago I was working on a Go project and I had an issue where I was using my runner too new of a version of software. And when I was trying to run it within my Kubernetes environment, the version of the software within the pod and the image was too new to use the version. So if you actually host your own runner, you could be very strict with the versioning that you use. So going over to the other side, the self hosted and this is the GitHub provided infrastructure. So by default today, if you were to click on actions and create a workflow, these are automatically provided to you. The interesting thing is that GitHub provides all the infrastructure for you. It will spin up the worker, the runner and do the stuffs and then just go away. There are a limited set of operating systems that are provided to you, which depending on what your project really needs to do could be kind of a strength or weakness. But going back to what I had mentioned earlier in the call is that if you're an open source project without a budget and all of these constraints, it's a great thing that GitHub sets up for you to allow your project to be and have a mature flow and put on that really professional face and have a mature system that you might be able to build a beautiful customer base because your software is tested and everybody knows how to use it. So lastly, the Git repository. As I said earlier, you're going to have your application code in there, which is a given. But when we start doing these workflows and these actions, files are created within the Git repository itself, which makes it kind of cool because any time that you modify your workflow, the modification to the workflow could be a PR and you could test that new workflow as a PR. So you can ensure that you kind of keep yourself safe, you know, the whole time. And it makes a really nice process and then allows you to get community contributions on your workflow actions. It's not a hidden thing. And I bring up and I want to go back to that hidden thing. Previously, back in my other positions at Red Hat, I'd use Jenkins back in the Jenkins I believe two days. And you know, the tough part about that is when you have an open source project and you have all of the code and CI taking place in a different place where a user or a customer can't really see what goes on. It makes it kind of difficult to understand the workflow of what actually it takes to kind of build the project. If there was anything special that had to kind of occur. And I guess the nice part about GitHub actions is that you can't really hide it. There's no like, well, you got to turn the wheel this way just slightly to get it to run. No, it's part of this workflow and people can immediately see it within your Git repository and know exactly what it takes to run and be able to kind of replicate it within their environment. And then the last item is secrets. Secrets are, you know, similar to what we kind of see with Kubernetes secrets. You can save specific verbs of text or so on within your Git repository. And this actually allows you to use those as environment variables or runtime variables for your GitHub actions, which is really nice so that way you don't have to worry about like obfuscating a password or doing that. It actually handles all of that for you, which is incredibly nice. So I covered a lot of stuff and I actually want to take the time now to explore repository. So hopefully we are seeing a repository right now. This is one for the GitOps Primer project and kind of just what I want to show is a few things here. So the nice thing, I will go back one step and say that this green check mark is the most stressful thing in the entire world. Once you have it and your project is passing happily and working as it should, you will do anything in the world to maintain that happy little check mark because it's almost like a seal of approval that, hey, my stuff is working. I promise you. And so that's one of the beautiful things of the little check mark. So let's take a look at like the last run that I have. This is kind of advanced run, but I just wanted to kind of show the fact that, you know, you can do multiple steps. You can kind of do parallel steps in GitHub Actions and then use those to just kind of do a full workflow of your application code and then when complete, push that to a repository. So that's just a high level of actions. We're going to go back to beginner actions in just a moment. So don't stress too hard as to kind of show where things are. And then going and looking at settings, I had talked about those secrets. And the project that we'll show today that we'll do later on has secrets as well. But as you see here, you define the secrets, key, registry, whatever, whatever you decide, and they provide a nice way to update it. You can just pop in a value here. And the nice thing is you can't really, you can't really see your current value. So it kind of makes it nice. You can't hack it that way, I guess, if somebody were to see that or try to get into that. So go back to the presentation. We've talked about a lot of stuff and you're probably thinking, okay, this is OpenShift Commons. What about OpenShift? Okay, D. There is a full marketplace of items and actions that GitHub and Red Hat have collaborated on together to provide you as a customer, as a GitHub user, a super simple way to just plug these items in. And so we could take a look at that now. So if I wanted to just push an item to a registry, I can just push this button here. And it gives me all of the kind of the documentation on how to use that. Some sample code. As you see here, we're going to push to Quay, fill an image. So it's really nice that Red Hat and GitHub have kind of collaborated together. And there is a roadmap that I'm sure that is accessible, possibly from the previous call that was had between GitHub and OpenShift, which I'll link to later. But they're constantly improving these. So you'll see even more advanced ones in the future. So back to the slides again. So let's get our demonstration. And we're going to start at just bare level. And we are going to create a Go application. We're going to store in our repository. And then we're going to create tests based off that. And then we're going to do a PR. We're going to do just kind of enhancements. Everything that you would kind of do in your simple project. Then we're going to bring it to OpenShift and use some of the amazing OpenShift things such as S2I. We're going to use S2I to build an image. We're going to push that to Quay. And then we're actually going to deploy that to an OpenShift environment. While we're going to test it and then deploy it to an OpenShift environment. And so with that, let's break out into the command line. So I, before we started this, I created a empty GitHub repository called stock. There's absolutely nothing in there now. So if we go to cb2 stock, have a readme file, and that's it. So we are starting at square one. I found this really cool stock application which will take and at runtime I can provide a stock ticker such as GME or IBM. And it will give me the value of that stock at the time. So it's kind of a cool thing. Like if you're just sitting in a computer and you're previously this year, this year, if you're following the GME stuff, you could get the quote instantly and be able to operate. So what I'm going to do now is I'm actually just going to get the required packages to run this. And we're going to do a go build. And let's just go ahead and run it real quick. So as you see here, it's like I said, it's a simple stock price app. It gives you the name of the company as well as the current price. So let's go ahead and add this to Git and then let's build some GitHub actions on top of it. Go ahead and commit it. We're going to click straight to main because we live dangerously. And so go ahead to our stock application here. Enter. Okay. So here you see our stock application and I accidentally uploaded the binary as well. So off to a great start, Ryan. All right. That won't affect anything, but let's go straight into actions and our workflow. So just by clicking the actions button, it will give you a series of potential options that you can actually apply straight to your project and it will automatically set up the workflow for you. So looking here, this workflow is made for your Go repository, which is exactly what we just created. So I can just one button and click this, verify that it looks good. Go build, go test, which are the exact items that I needed for my project. And then go ahead and do a commit. So what's going to happen is that our project is going to do an initial test run. And it's going to try to build our project and run the test. And as I said earlier, it is going to use that infrastructure that is provided by GitHub. So it's a really nice feature that, you know, GitHub provides for us. And so we're doing our build steps now, which went through clean, as well as our go test and our test passed in 0.8 seconds. And the nice thing is we get that green check mark that I was talking about earlier. So that means our build is clean and we are ready. So now it is time to kind of add some functionality to our program. We want to make it so that we can see the values that have been for like the last 52 weeks. If we go ahead and take a look at our stock application here, we want to add in just a couple lines right after the ask price. That's going to show us kind of our 52 week high inlows. We'll go ahead and put that in place. And I'm going to remove the binary, and then I'm going to just update it with our new code that we created and do two weeks. And so what's going to happen now is we're going to click this link here, and we're going to create our PR. And the awesome thing is just by that initial action that we kind of created, it is going to automatically test our PR for us. So when you think about this grant scheme of a really large team, if you can build this workflow and the setup to be fairly confident in the results of which you're going to get out of it, you can actually take this and your team is not pulled off to manually hand test these new features, these new functionalities. If the testing passes and all of your items pass, then you have a pretty good assurance that the things that you've done will actually kind of work in your environment and work for your application. So cleanup is done. It looks like we passed again in .9 seconds. We will be getting our green check mark here hopefully very soon. And all two checks have passed. So our build has passed as you see here. I'm going to go ahead and merge this and then to just kind of show complete confidence that things worked as expected back to the command line. So run it again and then we see you may be able to actually see the 52 week high and lows now. So we added that functionality. I didn't actually have to test it on my system. I just wrote the code third to get and let it handle the hard parts of building the binary, testing it. And so really cool thing about this as well is that if you think about the possibilities here. As an example, last week I was sitting in the middle of traffic in the passenger seat of a car in Chicago writing code against my application on my phone. And the nice part about that was is that I could just fire and forget and know that all of the testing was going to take place. I just have to worry about writing the code. And if it was successful, then I knew that any of my changes were good. And so let's go ahead and do one last one. And this one we're just going to kind of put a message into our app. So let's go ahead and modify our application again. And so we'll just put a simple message in here. It just says diamond hands if you try to look up the value of DMA. So we're going to go through the same process again. We're going to do our, the code test is going to take place. It's going to do our building and it's going to do our check. So we'll just kind of watch this go since it's pretty quick. And as you see, we had a build failure. What happened? So I did not put the ending bracket in. And so the nice part is I, since I did not commit this all the way to main or my main branch, I can actually take and save myself from breaking the build. So I will go ahead and modify this just within the GitHub UI, just kind of talking about how you can kind of modify this anywhere you are in the world. Now update it back at the change. And then our check is going to go through again. And we were successful for 8.8 seconds. And we got a green check mark. We will merge the pull request. And as you see, it was kind of cool because we got to do it on the command line, as well as kind of use the web UI to kind of do that, that test. So if we do it again, get our message as well as the ticker. So that was just a simple go application. And I want to kind of just do this scenario as that day one showing you how you can use like these GitHub actions that are pre-baked to automatically kind of do the things you want to do with a binary. So with that, we're going to actually now change gears and do some work with an image and source image. So a lot of this we're actually going to do in the UI. So let's make that happen now. So I went ahead and before we started, I forked Christian Hernandez uploader application. You all might know him from the GitOps shows. He is an amazing engineer. So I stole his code and we're going to actually apply some GitHub actions to it. And what this is going to do is we're going to take these GitHub actions and we're first going to build an image with it. And then with that image, we're then going to push it to Quay. And the cool thing about this is this is going to require us to provide some secrets. This is going to kind of be that next level up in regards to more advanced type scenario that's still kind of easy to approach. So we're going to go to actions and we're going to kind of freestyle this one. So we're going to set up a workflow ourselves and we're going to take and we're just going to start off with we're going to go a little simple and we're just going to do the S2I piece. We just want to make sure that we have all of our stuff in place. We want to make sure that the steps are correct. We have the builder image we want to do and we're not sending like builds that we're not ready for to Quay yet. So we'll go ahead and start this commit. And once we kick that commit off, we're going to take a look at the file and just kind of walk through what we're going to do. So on any pushes to the master branch or pull requests against the master branch, we're going to run this workflow. So any PRs that come in or any, you know, automatic marches to master are automatically going to get tested. There's one thing that we won't cover today since it's just like a little bit more technical, but you could set up a schedule as well to test your project every morning at 7.55. So that way at 8am, if it's broken, you can immediately start working on your application. The next thing you'll see here is this workflow dispatch, this blank line. The nice thing about this is that we'll show this off in a minute, but you can go to the actions and manually kick off this workflow. So let's go ahead and get into these jobs. So what we're going to do is, like I said earlier, we're going to do a build. We're going to run this on Ubuntu latest and we're going to check out our source code from our get repository. This action slash checkout at v2. This is automatically, I guess, known or built into GitHub. We're going to see a couple more of these as we go. Actually, on the next step, the next step, we're going to build an image and you're going to see this here. This uses redhead actions. That was that marketplace of redhead actions that I showed earlier. And these are pre-built items thanks to GitHub and redhead that came together create these kind of, I guess, many applications within GitHub actions that allow you to save a whole lot of time in regards to setting up your environment. And then with our source image stuff, as you see, we're going to provide our kind of image that we're going to create source image off of that we want to use the PHP application, the PHP base. And then any time that we create this image, we want to tag it as the image name of offloader and with the tags of the GitHub shop. The nice thing about this is that we can take that tag and image and we can either update a deployment with it and roll out the latest deployment with an open shift. We could just shove this into a deployment YAML, which our get off system could take over at that point. It gives us a lot of good starting points. And the nice thing is that it's a unique image name that allows us to be able to trigger and do events off of. So if we go into our GitHub actions, we see one's already ran, but we're going to run one anyway. This was that line that I was talking about that workflow dispatch. So we're going to go ahead and run the workflow from our branch. We'll wait for it to kick off. And again, we're using that infrastructure provided by GitHub. And so what we're going to do now is our image is building and hopefully be successful. So it's doing the source damage steps. As you see here, it's pulling the latest CentOS PHP page, PHP image, sorry. And then upon success, it is done. Because right now we're only building the image. So at this point, we need to add some more functionality to it. This would be a great thing to have if you had multiple open shift environments. You can do this stuff to push your image to Quay. And then when each of those remote environments or test environments or various environments or ready, they could just grab the image that would have it from Quay. So time to move on to the Quay steps. These are the steps that are actually going to require us to create some secrets. So we're going to go ahead and here. So as you see, pushed to Quay. What we're going to do is we're going to do a Docker login into Quay. We're going to tag that up later in the GitHub Shaw to be at quay.io, my Quay username, and up later with the GitHub Shaw. And then lastly, we're just going to push this image straight to Quay. So before I commit this code, I don't want to commit it yet because let's just commit it and we'll see it fail. But we need to do the steps of defining our Quay password as well as our Quay username. So I will go ahead and go straight to master again. And let's go ahead and go into settings, secrets, and then new repository secret. And we're going to do a Quay username or cook. And then I'm going to log into Quay and I will most likely be pulling this away when I create the next secret just because I don't have that much free space in my Quay repository. I would love projects to be able to use it, but I have to use it for various things. So I don't want to completely share that. So let's start here. I will enter the value here, but I'm going to just pull this kind of across real quick. Back in action. Okay. So now you see that the Quay password and Quay username are defined. So going back to workflow actions, as you see, we failed and we failed because we did not have those secrets that we needed in place. So we'll go back to actions, our image build, and we're going to run the workflow. So we're building the image now. And then we are logged into Quay and we're pushing that to the repository now. And we got our happy green check mark. We have officially taken and done a source to image with Christian's code, taken that package it up in an image using GitHub actions, and then sent that to Quay to be able to be used by multiple OpenShift clusters. So at this point, let's do some OpenShift. So I have an OpenShift cluster already deployed. If I can remember the name of it. All right. And so this is the standard token display token page. We will come back to this in a second. I will probably pull this across as well just to keep the token separated, but I will show you what we're going to do with the token in a second. We're going to use the token as well as the server address, the server URL, and a name space to deploy that image. So let's go ahead and write that deploy code, and then we will do our secrets. So back in here, we're going to go to our GitHub workflows again and modify it via the web. So you remember that first slide that I kind of showed really early on where we saw the build step and then the deploy step? Right now we're actually going to do the deploy step. And so how we're going to kind of start it out with, we're going to piece it together similar like we did with the build and then the push. Right now, we're just going to build the image, push it to Quay, and then we're going to log into OpenShift. And as you see, the OpenShift login is yet one of those things that OpenShift and GitHub well, GitHub had collaborated on to create this application within GitHub actions that allows you to kind of, you know, beat up your way of actually being able to use this functionality. So as you see, I need to set secrets of OpenShift server, OpenShift token, and name space. I will pop this open here. Go down the secrets again. New repository secret, OpenShift name space is uploader. Then I'm going to pull this across real quick so that I can put in my actual secrets and server name. And the secret that I'm actually loading right now is the OpenShift token. This is just the one that when you request the OAuth values, it provides you the token and it's good for X number of hours or whatever your administrator provides at the time. And then lastly, I'll be doing my OpenShift server. And then this is the API address, the 6443 address. So those secrets have been added. And we're back at our code here. I went ahead and added those items in now. So let's start the commit. And we are hopefully going to see those same actions take place, our image build, and then this deploy step. So as you see, we don't want to source the image, push the quay. That part is list on completed there now. And as you see, the build job is complete. But when we go and look at our actions that are summary, we see that we have the second deploy step that we just built a moment ago. And as of right now, we are just using it to log into OpenShift. And as you see, we're successful into logging into OpenShift so that we know we're in a good place. Now let's just take and deploy this application. So anytime that there is a change to the source code, this will take over and automatically deploy to our environment. So I am using just kind of a quick way to do this. This would be something that you've maybe used in a test environment, an environment that doesn't use GitOps. But I'm actually just going to delete the deployment, delete the routes, delete the service, and then use OCNewApp to create a new deployment based off of the image that I created in the steps above. And then we're going to expose it. So I'm going to do this in a PR. And then we'll just call this push change three, four requests. And our checks are going to kind of take place. And so the nice part about this is it's kind of very similar to what we showed with the go example. We're going to do all of our steps. And then even our PRs are going to be tested for us, making it so that if you don't have a readily available OpenShift environment kind of environment that you can actually just test the code and kind of be on your way. So we're waiting for the checks to occur now, refreshing here. So our build is actually already complete and we are on our deploy step. So as you see here, it deployed straight to the environment. But as you can see, that could probably be a bad thing that if you automatically deployed any PR that you've kind of accepted to run through your actions straight to your environment. So we're going to go ahead and do a file change on this really quick using the UI. And one thing that I wanted to call out is that our deployed needs the build process to pass. If the build does not pass, we will never get to the deploy steps. And then the last part we're going to add in here is this, this if statement. And what this if statement is going to do is that even if it's a PR, it will not execute this step here unless the branch itself is master, unless there's a push to the master branch. And what this is going to do is it's going to kind of save us from pushing when we're not ready or deploying when we're not ready. Or for example, if you're doing a like testing of multiple images, you don't want to just send those to acquire possibility to take up space or to not be potentially used. So we could put this in and only upon our master branch merging, we can, we're automatically going to run it. And so this is going to be kind of the final step in the piece. We're going to just see that once our build completes, it's going to stop before doing the deploy. As you see, it says pushed. So we'll go back to our summary. And we have a green check mark. And it's going to put a line in a circle through the deploy, because it did not meet the criteria to deploy it. So that's just a nice little like stopper just to kind of keep you a little bit safe and make it so when we verify that this image is good and ready, then we merge it. And then our default action that we initially set up will take place just here in a moment. And as you see, we merged it. And this is actually going to do our step of pushing it to our open shift environment. So I'm going to actually take now go back to the slides and kind of wrap things up and leave some time for questions. So I have a couple links here. The first link is to a presentation done by Red Hat and GitHub. Both the Johns show a very in-depth open shift and GitHub action scenario much deeper than this, showing all of those integrations in the marketplace that we showed earlier. They were the brains behind creating that. The second link you'll see is a link to introduction to GitHub actions. This is just a nice starting point that if I missed anything or if there's anything you kind of have questions on, it provides that really detailed write up on how to kind of get this off the ground. And then finally, if you would like to kind of get a hold of me, if you have any questions that you can get the answer in chat or if you watch this at a later date, here's my Twitter handle as well as my email address. So with that, I will stop sharing and we'll open up the questions if anybody has any. Thank you, Ryan. Actually, could you put back your last slide just for a few so people have time to capture that really fast? Yes, for sure. Definitely. Okay, there we go. Thank you. That was a great demo. I think that will also share your demo. Actually, my ask to you is your actions link, does that contain the demo links that you had in there? No, I will actually add those in right now. I will go ahead and put those just on the next couple of lines here. Thank you. That's perfect. All right. So first question, after we do our workflow, is there a way to create a kind of template of it? I mean, many apps would probably have the same steps and changing it in one place would be cool instead of doing it in each of the rebos. That is something that I don't have an answer for, I will say. I actually can see how that would work really well. And the only, I guess, concern that I could potentially have or I could see with it along the way would be that first step that we saw in our actions where we pulled down our code repository because it kind of expects it to live kind of together in that same repository, the actions and the code. So I don't know if there's any templating. It would be amazing if not and maybe something that GitHub would like to implement if not. All right. We'll follow up on that one. That was a great question. Is there a way to rerun one step that failed or maybe start from it? So you can re-kick off the jobs. I do not think that you could do them this out of order. I can jump back. Let's go back to our demo here and let's see what we can do. If I'm in the second part of this, yeah, it looks like there's just a rerun all option. I can't seem, it doesn't seem like I can segment off and just do one job out of the collection. Thank you. And I guess a downfall would be if you were to rerun a job that's out of a grouping. Sometimes there's parameters or an image that has passed from one job to another. And so that might be missing, which could cause maybe some pain if you were attempting to do that. I just realized I was muted. Sorry, everyone. All right, Ryan. Since you're in the Emerging Technologies Office, what else have you been looking at? You look at things before we do. We take what you're doing and try to make the product better. So what can you share with us? So there's been a couple of projects that have been really kind of, in my opinion, game changers and they're actually already in motion to be hopefully brought into products productized soon. Describe project that I mentioned earlier. Describe project, what it does is it allows you to replicate data from, replicate persistent data that is from one OpenShift cluster to another or one OpenShift cluster to many. You will hopefully be seeing that integration within Rackham soon. And the nice thing about that is, is because then Rackham becomes your one source to take and distribute not only your application, but your application persistent data from one cluster in a failover scenario, or like one in many clusters to edges, edge clusters, or just even distribute your persistent data as almost like a deployment. And then the last item that I probably had was that first GitHub link that I showed for the GitOps Primer project. And what we're going to hopefully see with that project in the future is something within the OpenShift UI that allows you to go to that developer console and play around and say, for example, I found this jar file, it's going to throw it into the developer console and see if it benefits our group. And then from there, I can click a few buttons and then download all of that object GML and then use that to either deploy into development cluster or put into a GitOps tooling. It's going to be a really cool way to at first just download all of that GML. So as a developer, the nice thing about that is, is that I can just play in the developer console or play around in the CLI. And I don't really have to keep track of how I got my stuff running. The GitOps Primer project will actually do that for you. It will just extract everything that you did in that point and allow you to rerun it again somewhere else. So that is the two that I've been kind of the deepest with as of late. And hopefully you're going to see those in the next few releases. Awesome, thank you. And I dropped the scribe one into the chat. So I hope I got the right GitHub link for those of you online. It's github.com slash backcube, b-a-c-k-u-b-e slash scribe, s-c-r-i-b-e. So yeah, that is a really interesting project. Thank you, Ryan. And that's all for our questions. Do you have anything that you'd like to leave us with, Ryan, as everybody's diving into looking at using GitHub workflows? I mean, I think it's just an amazing part of technology. I do really like the fact that it is so forward-facing. I feel like it lowers the barrier of understanding and figuring how to run something because people can kind of see it. People will be able to understand what it runs on or how it runs. And that green check mark really makes you feel good at the end of the day because you know that it's going to successfully deploy if you follow the kind of steps in the repository. So I'm very, very happy that this exists. Awesome. Yeah, us too. Thank you. All right. And thanks, everybody, for joining us. And until next time, thanks again. OpenShift Commons, make sure you go to the Commons website to view all the events. And OpenShift TV also has the events, openshift.tv. So thank you again.