, this is our workflows repository. Go grab the one you need as you need it and it will never execute. So we're going to move this moving files in the UI is a little bit tricky. Yeah, it is. So I'm going to show it to you because it's definitely a major gotcha. You click into the file so that you can read it and you hit the edit button, which makes no sense, but that's what we're going to do. And then you can edit the path and then I can commit it. So let me go ahead and talk a little bit about what's happening before I commit this and we'll walk through what this workflow file is. I'm making it a little bigger for you. Yep. That looks good, man. To do this. The UI just went horrible. Okay. So this is a third party action. Okay. We're going to use a community developed action. You can find this action and get a marketplace. Is that a bad thing? No. Is it scary? Maybe. Right. It depends on what your constraints are. Is it going to take you a long time to go read what's in this action to figure it out? No. Ask a developer to do it. It'll take them 20 minutes. How do I know where this action is? Well, right here under the uses tab on line 20, right here, this is the namespace and this is the repo name. So if I just copy that and I go to github.com slash that here is the repo where that, that action lives. So I can look into it. I could read up on it. I can see how to use it. Whatever it may be, right? Here's all the information about how to use it. Here's examples. So if you're ever looking at a workflow and you're like, I need to know how things work, that's how you can find that out. Okay. So let's talk about this from the top to the bottom. The name just names this workflow. We could name it whatever we wanted. If we don't name it, the name is the name of the file. So the name becomes the file name. If we don't name it, I like to name it. I think it's easier to find the on declaration is the trigger. Okay. And we showed you the trigger of a workflow dispatch yesterday. Events that trigger workflows. I also showed you this massive document of all these triggers over here on the right hand side. Yesterday, we used a workflow dispatch, which to manually trigger a workflow, use this event. I am going to set this one up as a watch event. A watch event happens whenever somebody like adds a star or clicks the watch button on a repo. I'm going to use this event simply because we're not going to wait until next Monday for an issue to be opened. I'm going to try to show you a couple of different events today. Typically, you would run this one on a schedule like I have here and it uses the standard Cron syntax. So if you just go to like a Cron converter, convert Monday at 9 a.m. into Cron, and you can place it right in here and use a schedule as a trigger. Jobs never changes. It's just a declaration of the jobs that need to be done. Jobs that need to exist. A job is a collection of steps. You can have more than one job, which we will a little bit later. This job is called create issue. It has a friendly name. This is just for the UI. You can remove that and it will use this as the name. This is just for the UI to make it easier. For each job, and this is important to know about actions, each job is ephemeral. So each job will create a new virtual machine, which means that jobs do not do very well at talking to one another. So pretend I had a job that was save this file to the hard drive and then I had job number two that was read this file from a hard drive. Job number two will never, ever find that file because it got destroyed when job one finished up. Is there a way to pass data from one job to another? Yes. We're not going to get into it here, but it is possible. Jobs can set outputs and other jobs can read those outputs. Is the short answer. Jobs also run in parallel, meaning job one and job two run at the same time. This can be a problem if job two is dependent on job one. GitHub actions allows you to create that dependency. You can say job two depends on job one. So these are things that you can work around that we're not going to dive much deeper into than what we just did. Okay. But that's where we're at. So we have some, we specify the virtual machine operating system we want this to run on. All this action is going to do is make an API call to GitHub. So I don't care if this is on a Windows machine, a Linux machine, or a Mac, it's an HTTP request. It can happen from a mobile phone for all we care. So Ubuntu is the cheapest and fastest option, which this is still free because the repo is public, but either way, we can limit the permissions that this machine has to the API or this rather this job has to the API. In this case, I think that's a little outside of the scope. So we'll just delete it and we'll let it have the default permissions and it'll be okay. I hope we'll see. If not, I have it over here. I didn't test this. So I could be wrong. And it should be because it uses that token. So quick recap, we got a name, we got a trigger, we got some jobs. We got one job that's going to start a virtual machine on Azure that runs Ubuntu. That job has steps. Steps can have a name. They don't have to have a name. Again, this is just UI. In this case, it uses timeout pause, hold up, wait a minute. Uses, remember yesterday uses meant that it uses in action so that self-contained source code, action.yaml, maybe dockerfile, it's not calling a terminal command. It's just an action. So in this case, we're going to specify this action. And I already showed you that this is just a repository, but I didn't talk about this part. So in order to call on an action, to say I would like to use an action, you need to specify where it lives and a reference to it. In this case, that reference is a specific commit. Remember every commit gets a shot. We can look at that over here. If we were to go to commits, I'll zoom out just a little. And we picked this one right here. This one has a commit shot. It's right here. So I can specify a specific shot, which is helpful because if the developer of that action makes a change, it doesn't affect me because I'm pulling it from this state alone. And always this. Another thing I can specify when using actions is a release tag. So in this case for pandas, if I pretend this was an action, I could say at v1.4.1 and you'll see this with some of the checkout actions later. We say at v2 and you're like, wait a minute, v2 is not a big long hash and you're right. So I can specify a release tag, I can specify a branch and I can specify a commit shot. So I could say at main that gets scary though, right? Because main can change. Right. Oh, it's highly recommended that you use either a release tag because that is never going to change or a commit shot. Now, a release tag is just an alias for a commit shot just for whatever that's worth. So it just becomes a little more readable. I don't think there was a tag associated with this shot. I just went with what they recommended on their own read me. So we're going to pull from this one. Yeah. So really in this put, this is that place, Matt, where we're talking about, you know, if they're out there creating important workflows that have got to work right. This allows them to lock in a version. So if what Matt's talking about y'all is the idea of the developer putting what's called a breaking change. Okay. Suddenly they're going to be able to do that. Suddenly they put a breaking change in and then you don't know why Monday morning, why the thing just didn't work. So what you do is you lock it to a version. So if they do introduce breaking changes and things like that, you'll be in a good situation. Exactly. Cool. So we're going to say, Hey, I want to use that action, man. Go out to that GitHub repo, find that commit and grab that code and pull it into our handy dandy fancy Ubuntu machine. Okay. This action allows me, the user to specify some, some variables, some parameters, and it happens to be in the form of assignees, labels and a title. So we don't have Mona Lisa. Oh, Mona Lisa. GitHub fun fact. Ready? This, this cat, her name is Mona. Oh, wow. I will get my Mona when we come back. I actually have a Mona. It's really cool. Her name is Mona Lisa. So if you ever wondered if GitHub was gender neutral, it's not. It's a, it's a email named Mona Lisa. So it's very cool. Whole history behind Mona. I'll find my Mona on break and I'll bring her back. So we don't have her in our repo. So this is, this is what can trip us up. We don't have a username Mona Lisa. We don't have a username Octo cat plot twist. This is not a cat. It's an Octo cat in another GitHub fun fact. I guess that's just goofy. Look, it's actually got tentacles. So it's a cat head on an octopus body and that's Mona. So it's an Octo cat. So if you ever see that, it's actually just a reference to the GitHub mascot. And then Hubot, we don't have either. Hubot is like a, just something you can configure, kind of like depend a bot. He's really annoying and tells you to merge your pull request. But we do have Brooks Seahorn. That's me. Okay.  That's not true for every action. That is just what this very specific action requests that we pass to this value. Secondly, labels, we don't have any of these labels, which might cause this to break. So we're just going to say bug because I know that label exists. And we're going to give it a title and we're going to call it weekly, weekly team sync. And in here, they let us pass some markdown. So we're just going to leave it because that's fine. We will delete this link though, because I don't want that to break. And pinned means is it going to be pinned? That's false and closed previous. That's false, which would close last week's when this one opened. Okay. And lastly, we need permissions to interact with the GitHub API. Well, here is that super secret GitHub token. Remember yesterday when we managed secrets, we had the secrets context. We had to go into a repo and add a secret. Well, that's where this GitHub token comes from, but you don't have to configure it. So it's your repository always has one secret. You just can't see it and it's the GitHub token. And that's what the permissions up here were that we deleted. Those were the permissions that we're going to be assigned to the GitHub token. So we could argue that right now our GitHub token is over scoped. That's okay. The GitHub token is ephemeral. That doesn't worry me as we go forward. So I am passing that in as an environment variable to the virtual machine that this action then references. Is that always going to be the case? No. This is the difficult thing with actions is the creator of this action decided that's how they wanted to read this variable. It could have very easily been passed in as a parameter. Did they do it the wrong way? No. Did they do it the right way? No. That's totally up to how they chose to develop the action, which is why it's really important to go to the repo and read through their read me because they will show you how they're using these things. All right. So now we've moved it. We've talked about what's in it. I'm going to commit these changes. Let's see if we can see it. Let's go to actions. Still not showing up. Okay. So we've got it in the right place. The file looks good. Right. Everything looks good. So what are we missing? Actions is a little fickle. That's what we're missing. There's another secret and that's certain events only apply if they're on a default branch. So since this workflow is on our branch, it's never going to show up until it gets merged into main. So, okay. So we've got a feature sitting out there or feature or a, what was the word we used? We got an enhancement. We have an enhancement that's living on a branch. We did our workflow. We created our GitHub. We got our workflow file. We put our YML in there. We've done all this. This is on a branch. It doesn't matter. We've got to get back to main. Yeah. How do we do that, Brooks? Magic. It's got to be magic. FM, freaking magic. Could you show us? Oh, I think it's that green button. Exactly. GitHub is already saying, hey, you have some things that aren't the same. Your two commits ahead of main. You want to go ahead and start collaborating on that work now? And the answer is yes. So we're going to create a pull request. And in here, we're going to say merge team sync workflow into main. So that it runs. This PR does that, that, that, that, that, that, that, that, that, that, that. Right. Explanation, something, something good. Right. We're going to create that pull request. I think we're going to run into a problem. Yeah. Merging is blocked. Right. You remember why we set up branch protections. We said we need a review if we want to merge. So we're going to go ahead and we're going to request a review. Once we get that review, it's going to come through and we'll be able to merge. So we've requested a review from Brooks. He's going to go in and improve and then we'll be able to merge this soccer in on my side. I literally just did a refresh on my screen. I'm sitting right now under my, uh, in my inbox, which is just in the top right. It's that little bell up there. I saw a blue dot. I clicked it. Boom. I click it. I can drop right in. See what's going on. I can comment on it. LG IMO. I can do a comment on it if I want to. You see the comment there? Yep. Did you click the approve button? That's funny. I don't have an approved button and y'all, this is not me making stuff up here. For some reason I don't have an approved button. Yeah. It's, it's so hard to see and I'm glad you're running into that problem because this is something that I've missed a million times, which is the only reason I know where it's at. You got to go to the files, change tab, then you get a review button and then you can hit approve. Does everybody see that back it up, Matt, back it up. Let them see it.  So you see there, this is what I saw basically all. I did not see like, if I scroll down, there's nothing like the approve button and that's the thing is going to burn you. You're going to be in a situation. They're going to say, go ahead and approve it. And then you're going to be going, where is that button? And you're not going to want to say anything because you feel like you should know where it is. In this case, that's where it is. Look at the menu. You have a number one there. Obviously something's up. Go click on it. Yeah. So the, the mindset behind this is if we gave you an approve button here, how many people would just click approve to get that notification to go away? Or how many people would just click approve just so they can move on? This forces you to actually see the change, whether or not you read through it is up to you, but at least you see the change. And now you can click review. So I'm going to go ahead and, I'll go ahead and move it out. That's kind of the, the idea behind it. Cool. Quick approval. As you can see, the Brooks clearly didn't read through that and just approved it anyway. So it's not like it prevents it from happening, but it's just really important to know that it's really hard to find this. And that's the worst thing about a poll request. And again, listen to what Matt told us about that. The point was, is that I could just do, you know, LG IMO and send it. And by the way, that's what happens a lot. All the time. There's a lot of software developers out there. Yo, they're going to front like they, you know, know everything about everything. When they go to read the code, they don't have a clue what's going on. They'll kind of spend an LG IMO and it'll send it on down the line. What GitHub is making us do is at least go look at it, at least look and see what change is. And so that's actually a really smart way of kind of forcing the right behavior. So whoever thought of that, it's good on you, GitHub. Cool. We got our approval. Thanks for that Brooks. We're going to merge in. Confirm merge. Do we need our branch anymore? I don't think so. I think we never know gone forever. Not coming back. There has to be, I'm going to get hung up on this because I'm, there used to be a way to restore branches. So like, I don't know. Wait, why would I do that? Whoa, back up. Why would I restore a branch? I could think of a couple of reasons. One, I accidentally deleted it. Two, maybe I clicked close the pull request button and it got auto deleted. And I need to reopen all of that. Is LG IMO a sub brand of the Korean electronics company? Looks good in my opinion. You might also see LG TM, which is looks good to me. Yeah. Yeah. Or as I like to say, let's get this money. But yeah, LG TM, LG IMO looks good in my opinion. Looks good to me. So now we're at main cool GitHub. It's in the workflows folder. So let's go back to our actions tab. Now it showed up. There it is. How about that? We'll take a look at it. Notice how the one yesterday has a button to run it. The one today does not. Different trigger, right? Yep. Watch event. So let's go ahead and I am going to change this. I don't think unwatching triggers it. So we'll refresh it just to see and then I'll rewatch it. And that should trigger. Okay. They may move this to just stars. So I'll star again, changes. So it looks like watch events now only apply to stars. It used to be, you didn't have these choices with watch. You just could watch or unwatch. So I think that prevents it from understanding the trigger. But the trigger was I starred this repository. That's it. Watch, I can un-star it and I can start again. And we should get another run. I don't know if that's going to cause conflict because we just created two of these, right? So every time somebody stars it, it's going to run. Now this is horrible. If you had a super popular project and you were triggering weekly team syncs, every time somebody starred your repo, that's not a good trigger, which is why a schedule works better for this. However, to demo it for you, I changed it to a star. There are plenty of things you might want to do when somebody stars the repo. Like say hi, for example. So if we come over to our issues, check this out. We got these two issues that were just added. Brooks and Matt are both assigned to them. And if we click into them, they have this body and they were created by GitHub Actions. So that's so freaking cool and powerful. If you have a weekly standup or a weekly team sync where you're kind of talking about the same stuff over and over or the format is the same over and over. Somebody on the team is going in there and building a document every week so that you guys can do that. You should do them a favor and not let them do that to themselves. Matt, that is such gold advice right there because y'all think about scrum standups, our daily scrum standups where we're going to keep it. Well, we should do really be doing less than five minutes. Let's say it's supposed to be less than 15 minutes. Everybody stands up. What did you do yesterday? What are you doing today? What problems are stopping you from getting your job done? One, two, three. Boom. This thing's ready to go every morning. The team's got it. You just type it in, type it in, type it in. Done. Yep. And it's super flexible, right? So like, let's show you how flexible it is. All of a sudden, we decide that the team standup is no longer, you know what we should have done? We should have linked this issue so that it closed because now I have to go in and close it. That's okay. We'll close it. And what would it take to link it? Yep. We'll do it this time. So let's say all of a sudden, our team decided this is no longer the agenda. We want to change it. Well, how easy is it to change this automation? We're going to hit new issue, update the weekly sync issue body. Did everybody get that? He didn't just jump in to changing the thing. We started an issue. This is so important because again, not only does it let you track what you're doing, but it's also a way of communicating out and up. What's the team up to? What are we working on? Exactly. So I have my issue. I'm going to come back to this one and I'm just going to close these two out. Can I close the multiple ones? I thought you, dude, I thought you could. Can you not? So many things change. This is the only, like I also only ever really use GitHub from like a terminal. Sorry. Honestly, honestly going to say, we're not goofing here to set you up for another learning like seriously, like as you weak as you use GitHub, sometimes from moment to moment, just like using AWS up, there was a change. It changes. Okay. So we have an issue. We're going to go ahead and we're going to create a branch to update sync issue. We're going to create that from main, same workflow, right? Now we're going to come into there, grab that workflow, grab the weekly sync, hit the edit button, and let's just remove these two items. And let's say we don't want this. Great. We'll commit that. We'll put a good commit message. Yep. More if you need it. We're going to commit that to our branch. We're going to hit commit. Done. Come back to the code tab. Open the pull request. And this is where we can link it to the issue. Yep. So update, weekly, sync, issue, body, super detailed reason to make a change. Over here, we then grab linked issues. So it says, huh, you can use the closing keyword. So let's say closing or I think it's closes. It's closes. Yeah. Number. And now I can come up here. Does everybody see that? That is cool. That is cool. Just that keyword throws it right up there. So you're like, oh, what was the number? Don't sweat it. Type closes on a new line. Boom, drop down. Yep. Anytime you hit that, that number key, you can reference anything. So we have issues. We have pull requests. Yep. Whatever it might be, closes will link these. Watch. So I'm going to hit create pull request. And here it is linked right here. It's linked to this issue, which is super cool. We're going to do a quick review from Brooks. Yep. I just got the pop up over here. So that took maybe five, six seconds to make it his way over. We can see who's responsible. We can blame him when it gets broken. Review me. It's been reviewed. Give me a second, man. Graham, you know what? Speaking of, this is a cool time to actually talk about this. Here's a diff, right? This is a change now. We can see what I changed really quickly. This got removed in favor of a blank line. And this got removed in favor of nothing. So that's what he got to see. So when y'all get hit with somebody over your shoulder saying, okay, what did they change? There's your spot. That's where you go to and say, this is what they moved. This is what they put in. And you can say it with, you know, it's, for those of you who maybe are new to your career, there is nothing finer than to be in a meeting or to be asked a question. You go, bam, with the information, nothing beats that. Yep. Okay. So what's cool is, oh, here's the revert button. They have, oh, wow. Okay. It's so changed. Oh, it's so different. So we merge this and you'll see this issue over here has turned purple, which means it's closed. So I can, I'm going to delete this branch. I'm going to come back into our issues. And we'll see that that issue auto closed for me. So just by typing closes and an issue number, I automated the cleanup of this repository. That is not an actions thing. That is just a regular thing. You can do it on any file. I now have the update. So we'll come to actions. Notice how like this didn't run because I didn't click this button. So like when I starred this, it has a different trigger. So it's like smart enough to not run the same thing over and over. I'll start this again. We should get a new run very quickly. There it is. Shouldn't take more than a second here. This number will change. If we really want to know like we can click into it, it's done already. This is where those friendly names come into play is here in this UI. And there we go. We got a weekly team sync. It was assigned to Brooks and I. If we click into it, it now has a different body. So it was that easy to edit our workflow to give our team a new agenda. And then it's still automated 100%. Pretty cool. That can go for so many things, man. So many things can be automated with that way. Just get the thing done. If you're doing this, if you agree with me a matter on this or not, but it's almost like, if there's this thing you're doing constantly over and over and over again, and you can see it inside this interface, you could probably automate it. Always automate it. That's my thing. So I know I just broke a lot of rules and I committed this domain, but what I wanted to do, oh, actually I don't even want to do that. I want to make sure you guys have this schedule in case you take and fork this repo, but I want to remove that star thing because I'm going to use it on other workflows. So I needed to hurt the trigger on this so that it won't work for us. So I'm just going to verify that that happened. So now there's no trigger. If I come into actions, it probably, yeah, it probably throws an error. Yeah, it's going to say if I click into that, it should give me, right? It can't be shown next run. There's no jobs. It has no clue what it's doing because there's no trigger. So that's okay. That's what we want. So it brings us to our first break. When we get back, we're going to dive into setting up probably the CICD. We'll do the pages thing last. I want to get to the CICD part and we'll show you something that's more for developers because this was definitely more for any team member that might use GitHub. So exactly. All right. So let's take 10 minutes, y'all. We are back.  All we got from I&E was these backdrops. Well, hey, man. These backdrops are pretty sweet, man. We're looking good. All right. So that's not true, by the way. No, it's not. It's not. This is the rig. We both clearly are wearing I&E shirts. Anyway. And also the rig. All this stuff that y'all can't say. Yeah. Anyway, yeah. That's a cool little thing. I think, honestly, side tangent for those of you that care or maybe have kids and want a cute plushie. I think GitHub operates a store. Because that's where I got this. I think it's open to the public. So I think there's a GitHub swag store somewhere.  Just saying. Oh, man. They sure do. It's the githubshop.com. The GitHub shop. I think so. Yeah. Oh, it's just scary. You are a brave man. Oh, see? Why would you do that? Why would you do that? Look at that. I know. That's a that's a scary search. You didn't know where that was going to go. I had no clue. Cookie cutters. Yeah. So here's an entire store if you want to GitHub stuff. Okay. Whatever.  Oh, man. $10 for 50 stickers. That's not bad. Yeah. The stickers are really good quality stickers. Just for the record. Anyway, back to it. Let's jump into our next workflow. I kind of lied to you. My bad. Blame Brooks. It's his fault. I was like, thanks for the URL, Matt. Matt B, thanks. I'm going to go ahead and I'm going to close this issue just because keeping our issues tidy. So I know where to go in today. There's one more thing that I want to do before we jump into the DevOps developer side of thing. And that is set up auto link checking. Look through our docs to make sure links work. This is a really cool thing that you can do if you're managing documentation or whatever. This is this could get a label as an enhancement. You don't have to use labels, but you can. Yep. Yep. So for that, we're going to need a branch add link checker. And notice another thing about my branch names, like not only are they deliberate, but they kind of say like what their purpose is, like update this thing or add this thing or create this thing. Same with commit messages. It shouldn't be like I am going to do this thing or pull request titles. It's I did this thing. So not updating readme.md. It's update because that's what you are trying to do. You are trying to update it. You're not in the process of updating it as weird as it is. It's kind of like a internal best practice kind of thing. A lot of projects are really strict about that. So we're going to go ahead and create our new file. It needs to be in that special spot. Get her workflows. And we're going to call this a link checker. Dot YAML. Let me just copy the workflow. No pace, please. Okay. So this is going to check markdown links. And I'll zoom in so we can read this a little better. We gave it a friendly name. It should be very familiar at this point. This one's interesting. Right. We're going to use a new trigger. This is on push. Now we haven't been using the terminal. So push might seem weird to you. But every time we click this commit new file button, that is a push event. If you're from a terminal and you type in get push, quite literally, that is a push event and that will trigger this. So what's cool about this is we say on push, we want you to run this job, which is only one. It's going to run on an Ubuntu machine. It's going to have two steps. Here's a step. And here's the step. And what's interesting about this is this is out of date. So this uses this actions at checkout. And this is a special action. Anytime you see this actions, anything, that is a GitHub maintained action. Okay. Master is not a branch name that we use anymore. Right. That used to be main, but master has turned into main. And this is just showing that you could reference a branch name. I happen to know that actions checkout is currently version two. So we're going to check that to V2. But I know that. How do you, let's find out. How would we do that, man? That's a great question. We're going to go to github.com slash paste in actions checkout. Look, it's just a repo. It's not magic. It's just a repo. And I'm going to scroll down here and I'm going to look for the releases. Hey, and I can see, I can use all the way up to version 2.4.0. Version two is going to reference one shot. And if I scroll down in here, I can read the docs on how to set this thing up. And they tell me everything I might want to know for options.  And here you go. Simple as that. Okay. That's how I find that. So we're going to go V2. Then we're going to use this repository, which same thing. This is a community action, whoever this person is created this action. And the only way I know to use version one is because I went to this repository and I looked at the releases to see where things were. The only way I know what options I can path right here or pass right here is because I went to this repository and I looked at the documentation and I knew how to configure it. So what this is going to do is it's going to spin up a VM. It's going to run a git clone. So just like you guys cloned or saw me clone a repo yesterday, that's what checkout does. So all of the code in this repository is now going to end up in this virtual machine. That didn't happen for our issues one because we didn't do anything with the code. We interacted with GitHub. We didn't need to look at any of the files in the repository. So they never got moved into that virtual machine. But in this case, we want to look through files to see if the links in them still work. So we need them and this is how we get them. So this is going to basically clone them into this machine. And now we can do stuff with this action against those files. And in this case, we've set a couple options for visibility. We've said any file inside of the path docs slash markdown files that is a markdown file. Any file inside of docs slash markdown files will be checked by this action to see if the links are valid. Every time a push in the repository happens. And that's at the root of that repository, right, Matt? So right there at the root relative to the root, there's a docs directory and we're going to look inside there for markdown files. Technically, it's going to look like this. Oh, yeah, I'm obviously looking for the markdown files. But we're going to traverse that to a depth of two. Looking for our markdown files to process. Gotcha. And in this case, we don't have any and that's okay. But any time a push happens. Now, this is like, oh man, do we really want to check our markdown links when we make a push to a JavaScript file? Maybe, maybe not. So I wrote in here a little note that schedule makes more sense. If you just like scheduling your weekly standup issue, maybe you schedule a weekly maintenance workflow that checks your markdown files every week. This is just to show you that I can force a workflow to run on a push. That's all. And then I will delete the trigger at the end of the day. Actually, yeah, that's fine. We'll do that. We also don't have any markdown files. So I don't expect a miracle to happen. Yeah. You know, and y'all to really, I'm going to kind of punch you here with the idea of what Matt is teaching us. There are a lot of corporations that just recently went through some major, major, major work to look at their documentation. And what they were trying to find was offensive terms and inclusive language. Different companies had different names for it. It was a big deal. I know that at AWS, I was a big proponent for it because there was a lot of stuff. And, you know, it's not anybody doing anything evil, anything wrong. They just don't know. They don't know that's an offensive term. They didn't know there was an opportunity to include some inclusive language. The thing that Matt and what a lot of them actually did was they just created basically text parsers in Python. This text parsed through all the text. The thing that Matt just showed us here, that is an awesome way as it comes in the door to make sure those checks are made instead of waiting until you're downstream to go, okay, we need to check this. So really open your mind up to some possibilities there. As this stuff has been created, you can check it right there automatically to make sure that you're in a good space. Not to mention, it's just points for you. It's just points for you saying, no, that whole thing has been automated. We've got that. Excellent point. We got a question in chat. You can't check a private repo with this thing, right? As it cannot clone it. Wrong. I understand where your confusion is though. That's a good repo that contains the workflow files. So for this one, GitHub for everybody has the workflow files. If this were private, it still works. The actions checkout action will still work because the checkout repo is public. So it's the repo of the action. It's visibility that matters. If you had an action that was in a private repo, you could not pull that into other repos. I could set my current repository private and use all the public stuff I want. So public or private things can consume public things. Public things cannot consume private things. I hope that clears it up a little bit for you. I totally understand where that confusion would come in. Now, there are other things that you can build local actions to. You can write all that source code directly into a private repo if you never wanted it to reach out. So on this take, let's say I have a repo that isn't allowed to consume anything public. Well, I can write all the source code for the actions in that repo and call them from the repo. But I will always be able to get actions checkout because it's public into whatever repo I have, even if it's private. It's like the vampire theory, right? Vampires can't enter your house unless you invite them in. Same thing. Okay, so crazy. Check this out. It ran. I didn't do anything. And it's not on the main branch, right? So that's another thing. We still have a branch. So push events apply to all branches, right? And we can see that here. It's on the add link checker branch. Our other one down here, our weekly sync, is running every time a push happens or attempting to run every time a push happens because it doesn't have a trigger. So just ignore that. It's not actually breaking. It just doesn't have a trigger. So it's freaking out. This one though is just not working because of whatever, let's find out. So it says this job failed. Let's take a look. And here is a bunch of logs on why. So there's runs inside a docker, four packages. Can't find a config JSON. That's okay. Can't find the directory docs markdown files. So this breaks. So this might be something that makes sense to add in this pull request. If we are going to add this workflow and this is a hard dependency for that workflow, let's go ahead and create that now. So we will come over to our first. Let's open a pull request, right? Because we've got a little bit of work done. Good title, good message. We got a little bit of work done. So let's just go ahead and do this. We will link it to this issue so that auto closes. And when we're ready, we'll request a review. And you'll see, look, it has, since we have something with a push event, now we're starting to get checks that show up in this screen. So only things that are relevant are going to show up here. Notice how we don't see the hello world ones or the weekly sync ones. And there's not really a way to control all of that easily for this purpose. There's other fine grained things you can add to the trigger that control it, but we're not going to dive super deep into it. I'll show you a small example, but not super, super deep. So this is currently failing. That's great. We can click details. It takes us back over to where we just were and we can see why. So let's go ahead and add that. We need docs. What is the folder docs underscore mark down or mark down underscore files. And you've got your approval on the change. Okay. Perfect. So create a new file. It's going to live in the docs. Markdown underscore files. And we can't create an empty folder on GitHub. So I'm going to have to call this demo MD and like actually create a file. And let's just put a link in for the sake of watching this thing run. And we're going to say HTTPS colon slash google.com. We know Google's up, right? All right. We'll commit that to our branch. We're still not committed to main, but it's running. So let's try to watch it because this one builds Docker. So we can kind of see that. We can catch it, right? So this is the setup job that just is building the Docker image that is present in that actions repository. Now it's checking the links. We see it. We're getting all of this extra output because we said like be verbose. I did that on purpose. But look, all links are good. Nice. So we know that that's cool. And it's green check. So let's go in here and break that. Let's see what it looks like when it fails. Oh, and now look, the pull request will be able to merge, right? Every all checks have passed. So like from a CI point of view, you could say, hey, like now we're kind of running continuous integration on content, not on code. So we could see that everything is there. I'm going to go ahead and I'm just going to merge this. Now, and then I'll break it. Let's delete the branch. It auto closed our issue like we wanted it to. Pretty cool. I'm going to break some rules as I break this. We're going to make a commit to main just for demo speed purposes. I hope this is not a URL. I don't think this is a real website. And if that hits, that's going to be great. So let's see. That was a push event, right? I clicked the commit button. Push event fires. It's updating. Let's see. Let's see. Let's see. This is the weekly sync one that's always going to fail because it doesn't have a trigger. If we click on it, it might throw an error for us. It doesn't. So we'll go back to check markdown links. We're updating. We can come over here. And I can see this map sort of on the back side of a push event where like, did everything work? Is the URL up and running? Are we getting back a 200 okay response from the site? Yeah. That's the thing is you could configure multiple triggers. So you could say, hey, on every push that is not to the main branch, go ahead and parse all the links. Also on a schedule, parse all the links. Also when, I don't know, an update to that folder happens, parse all the links, whatever. Like you can set up all kinds of triggers for that. Now, look here, one dead link found. We got all this information about the links in that. So that's cool. So we know how to fix it. Now this doesn't, it's not tied to a pull request. It's not going to stop anything from merging. Or whatever it might be, but consider the next step to this. This is, this is one step. We just had an issue creation thing, right? We, on a schedule, we create a new issue. Well, what if we created a new issue if this failed? Like if this step fails, then we create an issue saying you need to check these links. That's a helpful thing. So like, let's see what Winkly Sync looks like. I think it might be easy to edit. Let's see. Yeah, this thing just creates issues, right? So we could actually, we could do that. We could steal this whole section and tack it as another step onto the link checker thing and say if failure. So meaning if the previous steps failed, then run this one. And it could create an issue and say, hey, man, like you need to go check that workflow run. You have some invalid links. And that would just automate that maintenance for you. It's kind of cool homework for you. If you want to try to tie it in and play with this once you get these notes. All right. Super cool. Let's take a look at our issues. Let's jump in and let's add our GitHub pages out. I think this is going to be quick and easy. So we'll start with that one. So the first thing I need is a branch, right?  You see how that flow happens, y'all? It's just the automatic way we start working. We have a new, we start with issues. We go in there. We create a branch. That's good. Or you can call it your feature branch for your coding. It's just this natural rhythm you start doing when we use GitHub. Yep, exactly. So add pages app. I am going to scrap this branch and I'm going to do this because of how GitHub pages works. First, I'm going to come over.  I'm going to come over to our settings. I'm going to come down to pages and I'm actually going to enable it. And I don't want to enable it off of main. I'm going to create one called GH pages. And it says no results are found. So I probably need to create that branch first. That has changed. You used to create it for you. So I'm going to create a branch called GH. That's a cool feature. I wish that was still there. Yeah, it used to create it for you. So I'm going to create a branch called GH pages. This is the only time I'm not going to have a deliberate name for my brands, right? Although that is kind of deliberate. It is the GitHub pages branch. So see, look, just by creating that branch, it automatically enabled GitHub pages on this repo. It didn't even think twice about it. So I could select a folder. I'm just going to leave it in the root and that's fine. So let's go back over to our branch. It automatically did that. So was it, wait, hang on, everybody. Hang on just a second. So we created a branch called GitHub dash pages and GitHub internally just picked it up and deployed it to pages. So y'all, that's that's a gotcha. Watch for that. That's some insider information. You're going to create a branch. You create a GH, a GH dash pages branch. Something else is going to fire. That's almost like a reserved word type thing. So careful. Very much so. So we have it set to serve our page from the root. So I'm going to create a new file. This will be super quick. I won't bore you too much with code. And honestly, it's not about the code. This is just a reiteration kind of day. We're going to call this index HTML. And we're going to paste in some HTML. Always about the code. We're going to commit that to GH pages. Guess what else just happened? That workflow to check our links just just fired off because it's not a push event. That is so cool. It's on a push event. That's simple people. That's simple. So we're going to add another file to GH pages. This is going to be main.js. The reason why I'm including the world's smallest JavaScript file is just to show you that pages is capable of interacting with client side JavaScript. Yeah. As a matter of fact, while that was running, as I go look at workflows, if I'm manager, if I'm just responsible for what's going on or what is going on, I can see right there what called it. Like I just see now create main.js. I can see it running. I can see pages build and deploy is running. I can see exactly what's going on. Yep. There we go. Lots of status about what's going on. It is taking place. So the purpose of adding a CSS file, an index file, and a JS file is when we showed you pages before, we kind of just showed you the markdown side of it. The truth of the matter is I could write real code if I wanted to and that's going to get deployed out to pages for us. So now if I come over here, again, it's not server side. That JavaScript just adds an event listener. If you know anything about web dev, that's all in the browser. So it's not server side and that's the limitation is it can only do client side rendering. That makes me wonder about how much fun it would be to use Rust for WebAssembly. So here you go. I had to clear the cache, right? I had to do that hard reload. Once I did the hard reload, here we go. Hello. This is the HTML that's in there. If we hit this, we get an alert, right? So like JavaScript works. All of this is client side rendering. So maybe you can't find a cool docs library that you want to do. So you write real JS or real HTML or whatever. Okay. Cool. Page is done. Look at that. Just found a great example out there on the web. You know what's great now? That's kind of done. We don't have to merge this branch. As a matter of fact, we don't want to merge this branch. How come? Why would we not want to just go ahead and merge that in, Matt? Because that is where GitHub pages is deploying the code from. So what becomes really cool about this is notice how main doesn't have an index file. It doesn't have a CSS file. It doesn't have a JavaScript file. And as I create another branch, like, let's just check this one off really quick. Okay. We'll say you're closed. And then we'll pick one to create a branch on. Let's do add a non-static web app. So I'm going to create a branch for main. Add non-static app. Now this branch has none of that fluff from GitHub pages. So all of the GitHub pages code is isolated to the GitHub pages branch. So to be honest with you, what we probably should have done first is set up GitHub pages so that we didn't have these markdown files or the dot GitHub folder over here. And we could have just had a very clean page deployed. It doesn't hurt anything that we didn't do that. But now when we make a change to our non-static app and we merge it into main, it's not going to show up on that GitHub pages branch. So we can continue doing private things or whatever we need to do in our repo while pages remains publicly deployed and independently managed for our project. Hold up, Matt. So this actually, this actually is not, y'all, I'm not making this up quite truthful here. So quite literally what we've got here is we almost have like a separation of concerns that we use in programming, like modularization. So we have this project. It's super cool. It could be code. It could be documentation, whatever. I like it. I don't want to mess with it. I want the GH pages to give it a nice front end for whatever reason. And instead of that mucking around with main, I can have this branch, which is like a first, what we call in programming a first class citizen in this ecosystem that says, this is for sending out JavaScript enabled. This branch, again, another first class citizen, this is our static. This is what we also sent out where we don't want. So is that kind of where we're going? Because this is some very inside stuff right here. Yeah. That's that's pretty accurate to how you could treat it. You just can't do fancy stuff like make back in calls, right? So yeah, yeah. It might be really good for like a project blog or some documentation or a portfolio or, I don't know, whatever you come up with creatively, but there is a separation of concerns. And now the question comes in, well, why wouldn't I just deploy a website? Well, let's pretend that I didn't already have my own domain. I don't have to buy a domain. GitHub supplies one for me, right? So if I'm a student or I don't care about what the URL is, which there's plenty of things I wouldn't care about the URL for, I don't have to buy a domain. I don't have to configure a web server. So no engine X here, no express here, no, no patchy, no whatever. I don't have to configure a web server. I don't have to configure any of the networking that I might need to allow access on specific ports. All of that's done for me. DNS off the table. Yeah, it's it's completely handled by GitHub. I focus on nothing but the code. It's kind of cool. And now whatever that page is, I'm assuming fits with the project. So it's, again, all in one place. So here I have a page deployed. Now I have the source code over here. I have the Docker image. I have all the automation and the CI CD pipelines. And I don't really have to go many places. I have the entire project management all shifted left right where the code is. So instead of, there's a document in Google that we use to describe this. But over on the network drive, we've got a Word document to describe something. The actual source code is seating in Team Server someplace. We've got JIRA for keeping up with what's going on. This is all one place, y'all. This is not a little thing that we just said. It's for a lot of people, that is a bane of our existence that we have all many separate disparate systems that don't talk to one another. Whereas with this, it's all in one place. Exactly. So what I'm going to do right now is I'm going to show you what the web application we're going to add is. Again, this isn't about the code. I don't really care about what's going on in the code. Did this, this is the wrong repo. Stand by just kidding, I lie. I got to get the right repo with the code in it. I don't have it. Give me two seconds. Let me pull this up. Basically, I want to show you this app running really quick so that you understand what we're going to do and you'll understand why it doesn't work. Or else this is not as fun. Like there's no point in CI if you can't see what we're doing. So it already exists. Where? I didn't know. It's everything so zoomed in. It's hard. Okay. So let me pop out. Oh, leave me alone. It's two and three. And this is our, what is this called? Demo app, I think. Yeah. Demo app. And is this an express app? I think it is. Yes. Is there not? Sorry, dependencies, right? So like, yeah, y'all hang tight. Hang tight. We're getting it. Yeah. So I got to install the dependencies and I'm glad you're seeing this because guess what? We're going to need to do with actions. We're going to need to install dependencies. And I just use the terminal command to install dependencies. And that's exactly what we're going to do with actions as well. Okay. Cool. So let's come to my super cool web app. It's super sweet. I know you're jealous. Okay. Nice. I know. I know. Let's go ahead. We're going to pick a number. We're going to say two. We're going to say four. We're going to hit add and two and four is 24. Right. And that's good stuff. Super sweet. Nice. Super crazy. Okay. That's what this currently does. That's it. So that's the code that I'm going to currently add to this. That's what this currently does. So that's where we're at. And some of you are like, yo, that's not right. And you're absolutely correct. So I got to add a couple of files. It's going to take a second. So feel free to ask questions if you have them as I do this. Well, the problem is we were just not going to be able to see this because it's server side, it's rendered from a server, right? And GitHub pages can only do static stuff. So we can't, there's no good way for you to see it outside of me showing it to you like that. That's okay. So we're going to commit this. This is just the JavaScript. We are going to add a file. Add that. Add another one. There's not that many, I promise. Oh, that's a few lines of code there, huh? A little bit. So many that I had to zoom out to find the button. Okay, let's see. That's that. We'll create a new file. Of course, what is in here? This is our culprit, right? It's not going to work after we quote and quote fix it either. So if you're expecting it to work after that, you're going to be sorely mistaken. That's okay. All right, last file. I feel like as I'm getting older, I can't type as well. It's a bummer. I don't even know how Rooks does anything. Man, I swear. Okay, so this is our web app. Cool. I'm going to go ahead and I'm going to continue to get flow for this. We're going to open a poll request. This is a non-static web app. Good title. Do something better than that. Good message. And I'm going to say, okay, cool. Create this. We're going to pretend that Brooks is going to review that and we are going to link this to what is it called? Static. There we go. I just got it over on my side. So our markdown check is failing because that Google link is not a real one, right? We hammered in that crazy link. That's okay. The good news is we can admin merge this if we really, really need to. So I don't think we will. Okay. You've got an approval from me. Perfect. So notice how it's saying I can merge, but the button is not green. That's because of this, right? So yeah, I can do it, but it's not like a green light to do it. The whole box is yellow. It's like, you should think about this. Double check what's failing. Thank you. I double checked. We're fine. We're going to delete the branch. All right, cool. So that web app that I just showed you, this super broken thing. It's really good. It's a good app. Also allows us to do stuff like this. Right? That's super fun. That's some super fun checking on your data type, man. Nice work. Yeah, there's some problems, right? Yep. Yep. If you know anything about programming and or math, you'll realize that you can't add letters together. And even the numbers in this application are coming in as letters. Okay. The actual code that's doing that, I think it's in here. This form is passing it in as text, right? That's just that it comes in as text. See type text. So that number is a text field. It's not a number field. That's okay. We might want to fix this though. We could very easily fix this if we use something like continuous integration, right? Like we wouldn't ever want this change to make it into our code base because it's broken, but Brooks just approved it. Well, what if we had a check that would have run our tests for us? And the good news is, is we have tests. I wrote some tests. So if we do NPM test, I hope that's right. Right? We can see like, hey, like these things are failing completely, right? And we could have GitHub actions run this test and tell us that. So let's go ahead and set up that. And that's called continuous integration. We're not going to go deeper than that on what it is. So like let's, so this is going to be interesting. So this is technically two workflows for us. The CI part and the CD part, but it was one issue. So what I might do in this case is create a new one that says config CI for the app. I realized that number, I don't know what number it is. What number was that? Baby, come back. Number seven. Number seven contains two work items. So this issue addresses the first one. Right. And I'm going to submit that. And what's cool is I can always click number seven and go see what number seven originally was. Okay. Okay. So sweet. This is definitely broken stuff. This fixes a bug, right? So we'll come into our code. We've got our issue. Let's create a branch add CI for app. And in this case, we want that MPM test to happen all the time, like automatically. I always want my code to be tested when something changes to this code base for whatever reason. So we're going to add a file. I said we're going to add a file. Do it. That is going to be .github slash workflows. And we're going to name this web app CI.yaml. Okay. And this is where actions gets a little bit fancier. First, we give it a name. Nothing new. We've defined two triggers. Okay. Two triggers. When there's a push to main, when there's a push to a branch named main, I could also say a branch named dev or a branch named testing, whatever. You can specify more than one. Whenever a push happens to main, this is going to run. So this is good for I've worked on the pull request. I've now merged it into main. I just want to run my tests one more time to make sure that the entire code base, now that that merge happened, just double checks out. Just in case there was any weird drift between the two. And it also runs whenever a pull request is created from the main branch. So whenever we create a pull request from main, we're going to run this workflow. Is this the most optimal way? Nope. Is it a good way to show you that two triggers can exist and we can start filter them out? Yep. And that's the only reason it's here. Okay. So you would want to think this through a little bit more pointed for your use case. This is a really good example. So when one of these two things happens, guess what? We got a job called build runs on Ubuntu. And what is this hoopla? Well, go ahead. Oh, no, I was going to say just what is that? Teen you up, man. What on earth are we doing with the no version? Yeah. So programming languages change, right? There are different versions of Node.js, which is a Node.js app. This allows me to test it against the different versions of Node.js. So the other thing I might be able to do is test it on Windows, test it on Mac, test it on Linux, right? I can test it with this language, that language, whatever it might be. It allows me to run these various tests. And I happen to know that this one is probably going to fail. Node 10 did some silly things that I think Express breaks on Node 10 now. So we'll see how that reflects. And I could be wrong. But since we are going to run the code, we're going to do stuff to the files. We need to run checkout. And then we can specify this matrix node version. So that's going to say, hey, for the current thing in the matrix, grab the version. So it's going to say the name of this step is use Node.js 10, use Node.js 12. So we're going to get a series of steps all in a loop. So that's going to iterate automatically without us creating like a for loop or a while or anything like that. If we say node version in brackets, it's going to treat that like a loop. And then all we got to do is matrix node version, or it could be it could be matrix dot something with Rust where I'm checking versions of libraries that I'm bringing into Rust, whatever it is, I get that automatic iteration. And we could call this whatever we wanted. Okay. But it's just already written. So then we're going to grab another GitHub maintained action that just does some node stuff. And it just ensures that it's using the right version of node to run the following commands, which happened to be NPM commands, just like I just ran in the terminal, right. And they have these as like individual run steps. This will install our dependencies just super quick. If we have a build step in our script, this will run. And then this will run NPM test, which is what I just ran down here to get this output. Yeah. Now, the reason that that just are just a quick question to make sure we're all clear. I noticed that the name down there are actually the runs. I've got three different runs. The first run doesn't have a dash next to it. So is that because of the name? Yeah. This just denotes an object in the list. This is YAML syntax, which we could really dive into on a whole day if we felt like it. Name is optional. I can add a name here. Name, build if there is a build step. Right. It gives us a bit of documentation then about what this thing is doing. And all name does is it shows up in the UI. So I'll leave this one without a name and you'll be able to see the difference in the name or in the UI. So let's go ahead and commit this to our ad CI. We're really zoomed in here. So just to give you a reason I want to point that out was that piece right there y'all. So that if, you know, if you're developing an application, if it's just, you know, again, it could just be a documentation repo. If there is somebody other than you say like the DevOps team or the help desk or whoever it is, who keeps an eye out for this stuff by using that name tag, you can make it easier for them to figure out what just broke. Okay, so we haven't opened our poll requests yet and we haven't pushed to main. So therefore this hasn't even showed up, right? So we probably actually need to get that to main. So let's see what happens. We're going to try. That might be one of those weird ones that has to be on main, but we're going to find out. We're going to pretend that there's a good body to this. Okay, we'll request our review right now just to get it out of the way. We'll link our issue. This closes, closes number, config CI. Cool. Now let's check. Here we go. Here we go. Poll request is what happened. Okay, let's see if I can show you. So a poll request just happened, right? So that's why this is triggered. So we can go into it and you'll see, look, the jobs, even though we had one job block is now running on 10, it's running on 12, broke on 14, it broke on, or might break on 15. I don't know why it broke on 14. Pretty sure that's what I use. Right, works on my machine not yours. No, I use 16, okay. So we'll see where else it breaks, if anywhere. We can, they all broke. Fantastic plot twist. They should all break right now. So there's that. We're going to prove, by the way, are you cool with that? Yeah, yeah, that's fine. We can just get out of the way, right? So we can come in here and we can see why it broke. There's no build step. This is CI, no such file or directory. Um, package.json, did I misspell that? Let's take a look. By the way, y'all, as I approved that, as soon as it popped me back, I see that my, uh, I approved something that broke dramatically. So now I feel like a big Ogoober. As you should. Let me go see if I misspelled that. That's possible. No, that's correct. We here, let's check the branch. It's there. Love me. What is broken? I don't know. Again, we're not going to spend forever troubleshooting. If something goes wrong, um, I would try to get this quickly because the next part's cool. If so, if not, it, uh, we're kind of dead in the water, which sucks. Path. It should be right there. Do you want to take a break, dude, while you debug? Yeah, I think that's actually a good call. We're at that time anyway. Okay. All right. Everybody welcome back from break. I hope everybody had a chance to, uh, jump in there and do the evaluation. Adam got it posted up for us. So again, what do you get a chance to jump in there? Let us know what you think. Meanwhile, back in Vegas. I'm done done. The chips fell in the right direction and the problem was simple. Uh, it's so it was a pathing issue. So GitHub actions assumes by default that we're in the root of the repo, but I got all fancy and nested all of this in this folder. So I needed to go update that and you'll see it's still failing, but this is the failure it's supposed to have. So it's still failing now. Uh, but it's no longer saying that it can't find what it found. Right. The tests are now failing. So this might be a problem when we get to putting this into a Docker image. So I might move these files, um, out to the root of the repo, but before I do, let me show you how I fixed it because this is a neat feature that is new to actions. If I switch to the proper branch and we look at the CI, all I did is in the job, I set up some defaults and the default was anytime there's a run step, which is our NPM problems here. What was failing is it couldn't get our dependencies because it didn't know where to find the file. So every time there's a run step, the working directory is now set to be the proper directory and it's able to run our tests as we expect. Makes sense. So that is, that was the initial catch. As a result, I think I'm going to move these back into the root of the repo. I don't think that'll cause a problem, but it might. We're going to try to do it without moving it first. And if we have to move it, I'll move it and it is what it is. So we're currently failing though, and we can see that in the pull request. So let's go look where we would actually see this because we're doing work. We're like, oh no. Some checks. All checks. Yikes. This is failing. So like let's click into the details. We'll find out why. That's the markdown links. Of course, I picked the one that we don't need. The one that is allowed to fail right now. So we'll come into here and we'll find out why. And the test failed. And the reason is it can't find any tests. How about that? So let's go ahead and just pop in here and we'll add the tests really quick. They're simple. So if we come, let me pull them from my thingy. Where are you? Where are you? Okay. So we're going to switch to our branch. Add a file. That file is going to be in web app or sorry, demo app slash web app. And then it's going to be underscore tests underscore. And this is just a, what just the testing library expects. This is going to be different for your project. I'm sure nonetheless. So we're going to add our tests. Super, super valid testing here. And we're going to run the commit and that's a push event. It's taken place, not on main. So that's not what's going to run it. You'll notice the poll request ran it because there's this synchronized event that happens every time you update a poll request. So since we haven't set the poll request, there's a lot of like sub things that take place. So if we came over to the events that trigger workflows and we look at poll request, anytime a poll request gets assigned to somebody, it's going to run unassigned or labeled or opened or edited or synchronized, which is what happened. We just pushed an update. So we can limit those runs, just like we limited what branches trigger this workflow. What branches trigger this workflow? We can say only run on a poll request comment or only run if a poll request is assigned. So you can further filter down what triggers these things slightly outside of the scope. But let's see why we're failing now. We'll click into 12 and look our tests ran. So now we're failing because we have bad code. We're not failing because actions is broken. This is flat out saying you have one test and it failed. And there's the difference right there. We actually see the suites, the test suites are failing. Okay, cool. Yep. So let's come in here and let's collaborate in our poll request. We'll say this is the workflow. I don't really need to see that one. So we'll collapse that. And this is the test, which that's not the problem. Either. So we're going to need to go if we could cheat and just edit the test, right? Let's go back over to our proper branch. And let's grab the culprit, which is this add numbers function. And we are going to uncomment this set of lines out. And I think at this point we can comment these out and we should be good, right? So we just, we, we saw that we had failure. We went in, we fixed the code again, not a course on, on programming, which is why I just kind of blew through it like that. But we saw that we had failure. So we're going to go in, we're going to fix it since we ran a synchronized. All of this is going to run again. And I think we're still going to fail on 10. I hope we still fail on 10 because I'd like to demonstrate like the matrix because it does different stuff. So of course it doesn't fail on 10. Right. So now everything is there. It ran cool. We ran the tests. We can still click into it. We see we passed. So now I think it's safe to say that we could merge this into whatever our trunk is or whatever our dev branch is, right? This is a part where we'd probably have a feature branch merging into a dev branch, getting ready to be merged into a release branch before it finally makes its way back to trunk. In this case, it's safe to say that we can merge this without problems, right? Like our code works. I think, I think that's fair, but probably doesn't work well. Probably doesn't work well. So we'll show you, I guess, what changed. So let me come in here and I will just grab that file and I'll uncomment it. So you can see it working. Just maybe some people that's helpful for you. And let me start the server. So this is the change that took place. If we come to this and we try to add D to three, it says, hey, that's not valid anymore. And like, you're not allowed to do that. Okay. It's not, it's not still not a good app, right? And now it's saying everything's invalid. So that's broken too, right? Because it's still treating these as text and like I coerced it into numbers, which it can't, like it's just struggling. So again, bad code, code's not the point. The point was simply that we were able to set up CI to where our test pass, when we make these changes, they fail when they don't make these changes. And we did this all right inside of GitHub. We didn't have to do anything extra. No Jenkins, no, no nothing. We just were able to do it right alongside our code. But now the idea though here is Matt, just in case I understand it, what we're really seeing here is we're seeing the development process. So make a change, we test it. We make a change, we test it. We're iterating towards the right answer. Yep. And this is not just for developers too, even though we're doing it with code, like imagine that being your documentation, right? We make a change, we verify the links. We check the style guide, right? We make sure that a style guide was properly applied to our documentation. We alert the right people. Maybe at the end of it, we turn it into a PDF and go store it on a Google Drive somewhere. We can automate 100% of these steps along the way without the need to write code, right? Like these development tasks kind of exist. So I've been doing a lot of talking.   I want to go back to our profile readings. Because now that we see that actions can do stuff, I want to apply that to our profile readings. So if you remember how to get there, it's github.com slash your username slash, well, your username. Is everybody got that? So you're going to do github slash username slash your username, not maths, do your username. Remember, this is just a repo, right? Special repo that has its name the same as yours. So what we're going to do is we're actually going to do something fancy schmancy. I want you guys to do a quick Google search, super quick Google search for RSS feeds. I'll show you. You can find any RSS feed you want. Maybe you already know of an RSS feed. Let me shut down this really quick just so we're not using resources. So you can use any RSS feed you want. You can find one. What is one? Wow. You search RSS feed and you don't get anything good. Do slash.man Top RSS feeds. Here you go. Here's the most popular ones. Here's the top 100 for news. Pick one doesn't matter. Pick one that matters to you. Okay. And what you're going to do is I want you to copy the RSS link. We're going to need that link for the feed. Okay. I'll see that. Normally these things begin with RSS and the URL. That's typically what you'll see. Looks like Huffington's got a little bit something different. It doesn't matter. Typically right there next to that orange follow RSS. That's the link you're looking for. That's what you're going to want to copy. So wherever you're at, whichever one you're picking, grab that value. Yep. Grab RSS. Any link, you can find one that you like. You can grab a quick one for now. It doesn't, doesn't matter. You maybe you're going to change it later. Okay. But grab an RSS link. I'm going to use CNNs. Don't don't come after me with pitchforks. That's just again, it's a link that I'm going to use. So what are we issues? Who created issues? I probably created issues. What just happened? Yeah, I created issues. Awesome. So let's go through the flow. Right. We're going to create an issue to automate our profile readme RSS feed. And once again, y'all, we didn't just go do a thing. We went to issues first. We are going to use GitHub actions to dynamically update our profile readme with things we care about using RSS. Okay. Sweet. Done. That's my issue. I hope you're there. I hope you got where we're at. We're right here. Let's go ahead and create our branch. Add RSS feed. Action. Boom. Nice and simple. Now we're going to add a file. This is going to be super slick dot GitHub slash workflows slash update readme RSS.yaml. Okay. And I'm going to, you'll be able to fork this over, but it'd be super quick for you guys to actually just type it and just wouldn't take you long. I can, I think the formatting is going to get messed up if I paste it in chat. Um, let's see. Hold on. What I will do is I will come to GitHub for everyone. I will create an issue. And I'm going to say this is your RSS feed code and I'm going to come in here. I'm going to say this is YAML. I'm going to paste that and I'm going to say that. So if you go to the GitHub for everyone repo, you can copy the code from this issue. You just click this little thing up here. Okay. We'll cover it real quick. We're going to update the repos readme. Nothing special. It's going to happen on a workflow dispatch, which means when we click the button, it's going to update. Again, this is one that probably benefits from being on a schedule, right? If you want to update your, maybe let's take a step back. Like maybe you want to add your projects dynamically to that readme. Every time you work on something new, you want to update it so people know what you're working on. The, you have to decide what that trigger is. If that schedule is once a week, fine. If that schedule is every time you push to a specific repo or whatever, that's fine. You might have to tweak the trigger. RSS feeds kind of make sense to do like, hey, like every day or every hour, go ahead and update this. Fine. In this case, we're going to use a manual trigger, but just know that this is something that benefits from being on a schedule. I just want to show you something that you can do. That's all. We have a job job has a declaration. We didn't give it a name. Didn't give it a name. So it's just going to say update in the, in the actions thing runs on a bun to notice how it doesn't check out the code because it doesn't need the code. This is, uh, we're going to reach out to that RSS feed, that link you just copied, and we're going to make a GitHub API request. Honestly, I think Jason does check the code out just a little differently. Jason is a developer at GitHub. He's built a lot of like crazy GitHub things. So you can definitely look into his account, follow him. If you're interested in stuff, he's actually responsible for a learning platform that I'm going to turn you on to here in a minute. And we paste in that URL and we're going to take this commented stuff and we're going to need to copy this, right? It's, it's commented out now, but we're going to need to copy it because we need to configure a section in our read me where we want this to go. So there's two different steps here. Configure the workflow and then edit the read me. So once you have that committed to your branch, you're going to come on that same branch. You're going to grab the read me and you're going to edit it and wherever you want it to be, you paste in what you copied and undo the hash marks. And that's it. You can just leave that there like that. And that is where the RSS feed is going to populate. So we can commit those changes. We see nothing yet. Next step, pull request. Good title. Good body. Oh, is a good body. Create pull request and merge that back to me.  You're the only collaborator. Go ahead and merge that in. I'm getting nothing over here because that's just go loops back to you. So now we're in actions. We click this thing, hit run workflow. And as we run that, our profile read me will now dynamically be updated every time this gets triggered to pull the latest top five things from the RSS feed and update our profile read me. So this is just again, a non developer thing that you can do to make your read me a little more personal. Look at that. I didn't do anything but run actions. So get up for everybody. This is something you can do. Maybe you write a blog post and you want to update your blog posts. Maybe you have projects. Maybe, I don't know, there's a million things you can do. The latest hacker knows. Yeah. The latest you got to Ycom and you know, you pull the news RSS feed, you could pop that in there and make it look like you're doing stuff and you're not yet. Everybody's getting the latest hacker news right there. Exactly. Which is why the other day I asked if the links were manually put in because I said this looks an awful lot like something I'm going to ask you to do. And it does. But this was all dynamically pulled. And if we give it a couple minutes and we run it again, we're going to give five new things that show up there. And you can go to that actions read our repo from Jason. And you can see the different ways to configure it. You could probably have 10 things show up if you wanted to. Exactly. Lola, that is a very cool trick you just showed us. Very cool. Yeah. I'm glad you liked it. Super cool. I'm trying to keep this is for everyone is possible. And I feel like we just took a really deep dive into overly technical stuff. So this is a good way to reel it back in. So work on your own profile read me's. Think about how you can apply actions to them. And honestly, if you look up like awesome profile read me's, you're going to find a lot of them use actions to do cool stuff. And that's an interesting way to get ideas. So all right, we have one more piece. Just one more. We have one more issue. All right. Let's see what it is. Okay. And then we're going to talk about a little bit of stuff, but that's it. So then we could create an issue off of this and the aspect of time. We're not going to create another issue to break this up, but you'll see it was mentioned in a different one. So let's go ahead and create a branch for setting up our CD. So once again, yeah, other than the fact that we did that, there's your workflow again, y'all issue branch. It just becomes natural to work this way. Yep. And some of you, some of you might want to argue that this isn't CD. And I will hear your arguments and I will side with you, but this is the beginning of CD. Okay. So just we're not going all the way through. I'm going to need you to just work with me and pretend a little bit. All right. Can we do that? Can we do that? All right. Thank you. All right. So what we're going to do now is we have this code. Yay.  So we have this really ugly code and we're going to put this into, we want to dockerize this. So we want to create a container out of this. So that's what we're going to do. And we're going to pipeline that. So we're going to do our tests first. And once our tests are good to go, then we're going to build that docker image and we're going to store it in GitHub packages. And then we can pull it and run it from a docker container and all that fanciness caveat. Pathing problems might exist here. This is another one of those things that it kind of expects it to be in the root repo. I will try to fix it quickly on the fly. But I kind of expect this to break. Even though the workflow is accurate, it's totally going to be a path problem, guaranteed. So we're going to add a file to our workflows. Copy this. And we're going to say create and pub docker image.yaml. Now we're getting big. Huh? Okay, I got to zoom out a little bit. So this is one that you could probably find in the starter workflows. Like when you when you come over to a repo and you hit actions, you hit new workflow and you you look through here, there's probably one. Let's say docker. We hit enter. Yeah, publish a docker container. Right. So you it's probably one that was over here. I can't remember where I found it. Yeah, but I think it is. The point is I use official docker actions. So this is what makes me think that I just grabbed the one from the starter workflow. Scroll please is we have this like disclaimer that this uses actions that are not certified by GitHub. I don't think that's true. I think we're using actions that are certified by GitHub. So we'll see. We gave it a name. Check it out though. New trigger on tags. We haven't even talked about tags. Tags are a way for us to say this is a release. This is a stable release that we are going to send out. Okay. Which kind of helpful when we're talking about doctor images, right? Like we don't really want to go through the hassle of building them all the time. So for our use case, we're going to say, hey, like once all of our tests are good and we decide that we're ready to go, we will tag a release and that's going to get us a docker image that we can then deploy to wherever we want. Okay. Not exactly the ideal pipeline here. Just pretend. Come on. All right. So here we set some environment variables. What's cool about this is these variables now become available to every single job. And in this case, we only have one job. But if we had three, four or five, they could all access these global environment variables. These get set as environment variables in each machine that gets spun up. Okay. We're setting one just to point to the GitHub container registry rather than the docker hub. Okay. And then we're just going to name the image the same thing that the repository is named. So we're going to end up creating an image called GitHub for everyone. Right. Kind of a bad name, but it'll work. Whoever named it should be fired. So our job is going to be a build and push image. That's the declaration. It's also going to be the name because we didn't declare a name. It's going to run on Ubuntu and we're going to give it some scoped permissions. Now what we're actually giving permissions to is this GitHub token on line 32. Okay. We're going to say you're allowed to read the consents of this repo and you're allowed to write an image back to packages. Everything else you need to simmer down and sit down. Okay. No touching. Right. So those are the permissions that the GitHub token is going to have since we need to deal with the code. We're going to check out the repository. We're then going to do some setup steps like logging into docker in order for us to publish to a registry. We got to log in. So we're going to log in with the GitHub container registry. We're going to use our username as our docker username and we're going to use that sweet little GitHub token as our password. So I'm not configuring nor storing nor risking my actual docker docker hub credentials at all to do this. This is all self-contained inside of GitHub. GitHub.actor is the GitHub context which is metadata about the repo. The actor is the person that triggered the workflow. So if Brooks triggers it, it's going to be Brooks. If I trigger it, it's going to be me and it's going to change every time and that's okay because we're using the GitHub token as our password. So docker is just going to let us log in like that and that's what the GitHub container registry expects from us.  The next thing we're going to do is we're going to use docker's metadata action and you'll notice here's a release tag. Here's a SHA. Here's another commit SHA. We're going to use their metadata action to format what we want the tags to look like. What's really cool is this has output. You can't see it but we end up using it down here. You see it says steps, meta outputs, tags right here, steps, meta outputs, labels. Well, meta is the ID for this step. So we're saying steps up here on 23.meta.outputs, which we can't see, this action sets them though and then we're using them. We can find that out by going to this actions repo and looking at that action.yaml or the documentation. We can find out what outputs it sets. That is also where I got this crazy pattern of information is from that actions documentation. They have a couple different formats for the docker tag. This is the one I chose to configure. Lastly, we're going to use docker's build and push action to look at the current context and do its thing or build from the current context. This is why I think this is going to break. I genuinely think that it's going to expect all of this in the root of the repo. And it's not going to find it there. If it breaks, I will move everything to the root of the repo and we'll see what happens. And I can't set that working directory because all of these are uses steps. At least I don't think. What I could do is try, I'm okay with trying. Let's see, it was defaults and we'll say uses and we'll say working directory. And that is demo app slash web app. We can try that. The other thing is, yeah, okay, let's try that and we'll see if it works. Yep, give it a swing, man. I don't know that I can do that. So step one is done. We've got that set up and configured. It's not going to run because we haven't tagged a release. However, our other stuff is going to run because we're doing stuff that matches those triggers. Like when we open this pull request, guess what our CI is going to run. All of that's going to happen. We're burning a bunch of actions when it's right now. It's cool because it's free public repo. All right, so let's get the pull request open. We're going to pretend there's a good title. We're going to pretend there's a good body. We're not going to request a reviewer yet because we want to get a couple more things set up first. I guess I'll link it to our only open issue and let's get back to work because we're not ready yet. So let's come back to that branch and we need to add the docker file. All right, like we got all the docker stuff set up for the workflow for actions, but now we want to add that docker file to our code.  Boom, really simple. Okay, we're going to grab node. We're going to set the working directory inside the container. We're going to copy all of this stuff over and we're just going to run npm start. It's not going to be fancy. It's not an overly complex docker file. And okay, I don't have it. I'm going to add a, well, I'll skip it. I was going to add a docker ignore file, but there's only one thing in it. So it's not a big deal since we're not really caring about trimming this container down or this image down to be super, super small. All right, so the damage has been done. And I think, I think this will work, but break. Okay, so I'm going to go ahead and merge this if I can get our request my approval now because we're going to pretend that all of our checks were good and sweet approvals in. And this one doesn't run until we tag or release. So would I want to wait that long? Probably not. Okay, I would probably build that container right now once the CI finished. I would say, hey, this job depends on this job. Give me that artifact now. But just to keep these a little separate and it gives me an opportunity to show you tags. Right, so you got to work with me here. We're breaking some conventions so I can show you stuff. All right, let's just double check that it's in there. Cool, Docker file exists. Great. Let's create a new release. It's simple. Choose a tag. What do we want our release to be called? We're going to call it V1. That's it. We're basic. Okay, we're going to say V1. The target I can set to a branch, right? I can set it to a couple other things a little differently like if I was using get from the command line. But in this case, we're going to set it to a branch. We're going to set it to main. We're going to call this our initial release. And we could write up some documentation. Here goes docs about our release. Maybe a change log exists here. Just say it wink. So maybe a change log exists here. This is where you might want to specify what's changed between your releases. You can set this as a pre-release. That's fine. But we're just going to live real close to sun. We're going to publish that release. Why? Oh, I didn't tag it. Sorry. Sorry, I didn't hit create a new tag. Yep, you got to do that. Create a new tag on publish. Hold on. I need to have control over the tag, which is the problem. Okay, I hit enter. I didn't click that. There we go. Now the tag has changed. So sorry. The reason we need control over the tag is because in our workflow, we said trigger when a tag gets created that matches a specific pattern. And that pattern was V anything else. So if I tagged this breadcrumbs, it wouldn't trigger our workflow, which is why I need to do that. Right. So I'm not just attached to the tag that much. There's a reason. There's a reason. Cool. That's it. We published a release. It zipped up some stuff for us. Some things I've done in the past is use like pandoc to take markdown files. And when I tag a release, it converts them into PowerPoints and then attaches the PowerPoint to the release so that clients or customers or other teams can download the presentation if they didn't want it in markdown. Right. So you can tie in workflows to edit releases and stuff. But now that that's there, look, we should have actions. Where are you? And that was a commit to main commit. Let's see. What doesn't it like? So it's failure and valid type for on interesting. So it's saying that our trigger is invalid. So it could have just a bad space somewhere on tags. Oh, wait, I saw it.  Did you? Yep. You've got a double. You got to. Oh, no, it's you're OK. You got V star. OK, you're OK. Coming to me sideways. Whatever, whatever. It's probably a release, not tags. I don't see a tags in here. So that's fine. So pretend that that works. And in this case, we're going to do a workflow dispatch in the event of time. And just so that we don't have to retag a release. Yep. And I hope that doesn't hurt the actual tagging of the workflow. We'll find out. So pushes happen. That's not what we want. We come up here, create and publish a Docker image. Let's run this workflow. Should we do? This is the worst part. You got to watch paint dry. As you're watching the paint dry, feel free to update your your profile readings. And it failed. And my guess is invalid workflow. Why unexpected value uses? Yeah. So it's saying that this isn't valid. What's awesome about this is you're seeing some actions troubleshooting. Remember that default section? I'm almost guaranteed I'm not allowed to use uses in the default section. So if I just click right there in the error, it opens up the workflow file for me to write to it. And it annotates what's broken. And that's exactly what I thought. I can't use this defaults thing. So there's going to be a bigger problem. And that's this probably won't be able to find what we needed to. Yeah. But the point being right there is just how smooth and easy that was to get to the source of the problem. Because oftentimes we're doing we're talking about pipelines and trying to figure stuff out y'all. I mean, just to sit there and stare at it and y'all I have done it so many times through my career.  And you just don't simply have the output from your from your development environment to figure out what it is. That right there's a big deal. The fact that it took us right to the problem. Yep. So we're going to let it run. And we're going to see it fail. I'm guessing because right. They can't find the files, right? They can't like a tag is needed to push to a registry. So maybe it's not a file problem. Maybe it's it didn't. Well, it didn't even get to building this. So, okay. So we can come back and find that. Right. And you're just going to drill this whole thing down until you get to the bottom of that, which this is a no Docker image version has been generated. No Docker tag has been generated. Check the tags input, which is interesting. So we're getting we're getting some verbosity on the feedback so that we know what to look for. Again, we're not going to spend a whole ton of time here. It didn't like the tags couldn't find tags, probably because it's supposed to come out of a version. Which I don't know if that got tinkered with because of the tags. So now I'm going to go through crazy troubleshooting here. Yeah, no, don't need to. But it shows you how we can find it really quickly. Yep. So you'll have this if you fork the repo so you can edit just that little piece to that that's in the web app. You could if you do it all from this, you'll see that it builds just fine. And it would upload it to the registry. That's kind of the point of what Matt just showed you right there. Like if we were working on this together and all of y'all could do this, you can fork that repo, you can hack away on it, figure out exactly what's going wrong. Then what do you do? Pull request. Yeah, open a pull request. If you want to solve it, pull request. Let us know. Hey, let us know. Hey, I found it. I know what it is that we can review it and go, you know what, dead on, add it back to ours. The NARS is updated. Yep. That's a really good point. And if you want to contribute back to this repo, that's fine too. You don't have to, but you're going to get like contribution graph stuff and it's good GitHub practice.  We're probably going to help you. So yeah, there's a difference. So I'm going to add in one last thing. We're going to close this issue. We're going to pretend that this, oh, we already closed the other one. We're going to close. I'll leave this open. Some of y'all are going to need that code. We're going to add one last thing and I'm going to do it without an issue. As soon as the code tab loads, I think I can, I think I can. No. GitHub has its moments. I'm going to add one last thing. I'm going to break the rules while I do it. And I'm going to stage workflows. I'm going to stage some workflows for you. Actually, I'm going to do this differently, I think. Yeah. So if you're, if y'all are going to fork the repo, wait a second. Don't do it yet. Yeah. I'm going to do this differently. Hold up a minute. I am going to add a file, but instead of creating a new one, I'm going to upload one. Hey, I figured this might be fun. Actually, I do need to create the folder first. Okay. Let's see if I can create that folder. Y'all, I don't know where he's going. I don't know what we're doing here. No, it didn't let it happen yet. Oh, it created it as a file. Oh, no. My goal is to show you can't just create empty folders. You got to create like a, like a, like a touch to file. Yeah. Yep. Readme.md staged workflows. Here are some examples for you. We'll commit that. Oh, me. Oh my, the demo gods said not today. They did not. This is why everybody knows are the worst. All right. One more time here. Staged workflows slash no, no, no. Readme. Staged workflows. By the way, there has to be a space. What's that thing for you? Yeah. Give it a space. Yep. Give it the space. Here are examples for you. Wink. Wink, wink. Okay. Cool. Great. So I'm in the stage workflows thing. I'm going to click on add file. I'm going to say upload files, which is cool because now I can drag and drop files and I don't have to do all that crazy like copying, pasting of the, the get flow, everything. So if I come to home, they come into INE, I should have all of my source code files right here. So it's like this out. I can just copy all of these. These are all YAML files and I can drag them right here. And that just did the upload on all of those files for me, which I can then stage workflows, right? That's a commit message. I hit commit and it's going to go ahead and it's going to add all of these.  They're all right here. So I want to talk about a couple of these and then we'll get you guys out of here because it's Friday. So we looked at our check markdown links. Boom. It's here. We looked at our create and publish a Docker image. Boom. It's here. The next step could be taking that Docker image and deploying it to ECS, right? Spending up a container running Docker. This one actually goes through an entire build and tag process again, right? But nothing stops you from plugging this into Amazon. Nothing stops you from plugging this into Google or Azure or whatever. Here's an example workflow because some of you guys said you were a little a DevOps-y. So I would leave that example workflow in there for you, right? Which is why I said, I know it's not quite CD, but you put these pieces together. You got yourselves quite the CI CD pipeline. Okay. All right. Thanks, Matt. You're welcome. We've talked about the scheduled weekly sync and we did the update read me. Here it is. If you need to copy it because of that issue. And we did the CI portion where we ran some NPM tests. Okay. Let me see if there's anything in this file that's worth shitty chat chat. Now, first and foremost, whenever a push happens to the branch of release, this one triggers, that makes sense, right? We want to release code to Amazon when we make a push to the release branch. We just automated deployment. What up? We'd set some environment variables. Remember, setting GitHub secrets right here might not be the best play, but there's other places to set them down here. All of these secrets are stored inside of the repository secrets. And then the environment variables are read in. This is a specific commit. This is a release tag. I'm not seeing anything that's jumping out as... If you want to run more than one command in a run step, you can use some YAML syntax to run multiple commands. Okay. That's, yeah, I think that's about it. So what I really want to do, push that in. All of that's pushed. All of that's ready to go. If you want it, fork it. Yep. And you have all the notes to include all the code that exists, which you saw how bad it was running at your own risk. It's all there, but that should give you all the examples you might need. You got the project board. This is also a public repo. You can always come back to this and reference all the closed issues, what we talked about and what we did. And I just want to point out, we put on this whole three-day boot camp, and it didn't cost a single penny in GitHub fees. And we did a lot of stuff. Yeah, we did. And so going back to what's the catch, the catch is this is a public repo, and GitHub can now use it to train something called co-pilot, which I guess I'll leave you with because it's cool. Check this thing out. Co-pilot, my VS Code peeps, is a, I'm trying to zoom out just a tad. Okay. Co-pilot is an extension for VS Code that I do not have installed on this VS Code. Of course. So we'll install it really quick. I'll be careful with the one he's doing here, y'all. If you want to make sure, make sure that it's from GitHub, because people love to name their stuff after other things, and so you'll download some bad stuff. Yep.  We're going to leave you on. Co-pilot activation failed. Why? Well, let me register. Boo, hold on. I'm going to share a different screen with you. Let me grab my personal workspace, where I know these things exist. So you'll never write code again the same way. If you don't know what co-pilot is, is basically what this boils down to. Yep. And I just share VS Code specifically. Cool. All right. Oh, now all my Zoom windows are messed up. Hopefully we can see VS Code. I just lost the chat, so hopefully that's true. We got VS Code. Yep, we can see it. We can see it. I'll try to zoom in here for you. Awesome. Oh, that's too much. We'll close all of this out. Don't save. Don't care. All right. So I have co-pilot running over here. You can see it down here. It says, hey, would you like to disable co-pilot? Never. I can close the terminal. We don't need that. So if I were to come into whatever this is and say, I'm going to write, we'll just say JavaScript really quick, a JavaScript file. And co-pilot supports much more than JavaScript. I can do something like this. I can create a comment with co-pilot. Trying to make this a little bigger for you. And I can say import, express, and create a web server. And if I hit enter, it writes all this code for me. And it's sometimes correct. Use, there we go. It even knows the comments that I want. Listen for requests. And it'll write a lot of code. So there. Server is listening there. I've not written any code on my own. So I can just come down here. And there we go. It even had an idea. So this is what the catch is. GitHub is parsing all these public repositories to train this thing. So we can say create a route to handle the requests. Right, Matt B. Exactly. Yeah, but the thing about Matt A is that it is a little bit spooky. This is one of those things where if the product is free, you're paying for it somehow. You are paying for it somehow. Right. So pretty cool. Well, now security folks, fun fact, number 400. I'm sure this number has changed. Cool. Stop sharing. We don't need to anymore. I'm sure this number has changed. However, at one point in time when co-pilot was really new, it was responsible for 40, like the code that it would put up. 40% of the GitHub co-pilot suggested code was vulnerable. You still need a developer.  You're not going to automate yourself out of a job. Simply co-pilot parses public repositories. Let's think of who creates those public repositories. Tons of students, right? Tons of people learning to code, right? So half of co-pilot suggestions or almost half of their suggestions are written by people with little to no experience. And they were like 40% of the suggested code was vulnerable. So it's important to set up the pipelines around something like co-pilot. Co-pilot's not limited to JavaScript.  Co-pilot will write your Docker files. Co-pilot will write go for you. Co-pilot doesn't touch Rust. Actually, it might, I don't know, if you... I haven't even looked, dude, to see if it would do it. I would be really reticent to try that because Rust can be so tricky. As far as, you know, like ownership and stuff like that goes, it may take a minute for them to get something like that to work. At the same time though, Matt, couldn't we just as easily? Because I saw that we did have access. For those of you who don't know what a code guru is, is an automated system in AWS that will look at certain code, not all languages, but certain code languages and scan those. We can make that part of an automated process on the back end, couldn't we? Most likely, yep. There's probably an action for it. If there's not an action for it, as long as there's an AWS API for it, you could write an action for it. There we go. GitHub offers something called security folks. She might like this. It's called CodeQL. They acquired a company called Semmel a little over a year or two ago, and they brought in a different type of code scanning. It's not static code analysis from the point of view of like the typical, like static analysis that you might do. It's a pattern, like it observes the coding patterns that your developers have implemented and tries to detect vulnerable patterns in their code. And that is a direct feature, especially for enterprise GitHub that you can, and you can configure it on your repos. It's called CodeQL, and it fires off through GitHub Actions. And you can set all of these really interesting rules. There's a giant bug bounty program for it to write your own custom code queries to see what's pertinent to you. And CodeQL has found it's responsible for finding a ton of vulnerabilities and helping update all the CVEs that we see depend about you to say, hey, this is vulnerable or that's vulnerable. So CodeQL, you can tie that right in. That's a really cool thing. It's not a standard static analysis tool. You would still need to run static analysis if you wanted to be super covered, but it is possible. You have any parting thoughts for us, Matt, before I throw in... Actually, I'll start with... Oh, yeah. Look, I'm so GitHub, my cup has Mona on it. Oh, man, what a goober. Y'all, honestly, when it comes to... There's at I&E, we're really focusing, you know, not on what the industry wants you to learn. We're focusing on what the employers want, okay? Which means that we do things as like, Nellie will be talking to some of the biggest companies around there that hire IT staff, but this is also my personal experience. Being in the rooms with Fortune, probably every one of the Fortune top 100 companies, walking around and this is something I kind of did to myself. I would look at their laptops. Like if I was just in the back of the room talking with some folks, I was doing a lecture on something like that. I would look at the tools they were using. And typically these are the things I would see. Visual Studio Code, obviously there's coders in the room. I would see stuff like Terraform. I'd see Slack and I would see GitHub. This is a big demand skill. This is what folks are looking for. So anytime and again, thank you all so much for showing up. Huge deal for y'all, to us, for y'all to show up and be a part of this and see this delivery of this GitHub for everyone. But for you personally, I'm really, really, really going to encourage you. Keep working with the skill. Make this your daily thing, even if you're continuing to learn. Set up a repo for your notes. For a particular subject that you're studying and start putting notes in there. And go through the whole process. Issues, branches, do the whole thing. So when that day comes, when you're either at that job interview or congratulations already have the job, when they say to you, clone the repo, fork the repo, open up a pull request, your reaction simply is, I got this. Yeah, one of the ways that I really got involved when I was new with adopting GitHub, was I have like profile files, right? Like my dot files on my, my max and my Linux, right? Like both of those machines have like my Bash RC or my whatever config, ZSH config, right? For my terminal. And every time you reinstall those operating systems or those tools, like, you got to go through the pain of like reconfiguring them. And all it is is just text in a dot file, right? So consider creating a repo that's, that's for machine configuration where you just simply store all of your dot files. And then you can quickly set up your terminal if you ever need to reinstall your terminal app or whatever it might be. That's, that's how I got started is I did that stuff. And then I started storing like scripts and small stuff to help with my daily work inside of GitHub. And then that, that stemmed into now I'm doing applications, Terraform files, Docker, you name it, it's all there. But definitely start small, right? Pick something that matters to you in that moment you need it. It's all going to like turn on.  Exactly. It's like one of our, one of the labs that I'm working on right now for our AWS track is you are completely out of luck. You don't have access to anything. And you've got to rebuild an environment. What are you going to do? Well, more or more to it, but at the end of the day, it's GitHub. It's pulling from the repo that's got your infrastructure as code in there, pulling it in there and throwing it back out. And again, having those GitHub skills, y'all, it's not going to be a nice to have in times to come. It's going to be a requirement. You're going to be expected. Like they're not even going to ask you, do you understand GitHub? There's going to say, hey, you need to fork that repo and figure out what's going on. That's going to be the whole conversation. Yep. So thank you all for your time. We're happy to hang out for a couple of minutes and answer any questions you might have. I'm just seeing a bunch of excited and thank yous coming in. Yeah. Thank you all. Thank you all so much. You're way too kind to us, especially Brooks. You shouldn't be that kind of Brooks. Yeah. Well, it's actually Matt that, you know, you have to be kind to him. That's all we have. I mean, bootcamp is wrapped. So enjoy your weekend and we'll hang out. And again, if you guys would, if you guys want to fill out the survey, we'd really appreciate that because that way we can actually say, hey, we actually did this thing. So leave us alone. That's true. Yeah. They kind of like to know that we do work.  If you want to close things down, we're just going to keep running our mouths. I kind of half lied to everybody when Matt said, when I said I didn't get anything from AWS. It's one of the funniest things for those of you who don't know the mascot of Amazon is a little character called Pecky. He's supposed to be peculiar. And when we first got that, we found that it was actually a USB drive and nobody at all used it. We all thought it was a security trick. You're like, if you plug that in, you're getting a call. Don't do it. Yeah, right? Don't do it. I, uh, when I was... Thanks, Patrick. I got really into social engineering early in my career. Like, because again, instructor, people, like the personality side of it. So I have cufflinks that are USBs, like they're USB cufflinks. So I had like whatever nefarious stuff I would want on those USB cufflinks, and I would just try to social engineer in my place to plug into places to plug in those USBs. Wow. Thanks, Matt B. Thanks, Lola. Hey, by the way, real quick about Lola, that's, uh, Carolyn, as you see there, she's the one that's got it rough. She's sitting in Tokyo. Oh, yeah, you're way crazy. She is very late, y'all, interacting with us. So thank you so much, Lola. That's awesome. She's probably laughing right now at me. Mm-hmm, yeah. 5.15 a.m., yep. On a weekend, come on. Yes, on a weekend. Two, two, two, well, cool. All right, so I think we're done, man. So if you guys don't have anything else, again, thank you. This was really cool of y'all to show up, participate, be a part of this. Wish you the best of luck. It was so fun. Absolute best of luck. Yeah. And you would need just fun. Yeah. And again, imagine if we'd been in a room, there would have been yelling and throwing. Things would have been thrown. Lots of throwing. There would have been throwing. So with that said, on behalf of myself, Matt, the awesome producer, Adam, everybody at AIONE, thank you all so much. And with that, Matt, click the magic button.