PBS_2025_02_15
An audio podcast where Bart Busschots is teaching the audience to program. Associated tutorial shownotes are available at https://pbs.bartificer.net.
Automatic Shownotes
Chapters
0:14
Introduction to GitHub Pages
1:12
Revisiting Web Apps Journey
3:09
Entering the CI/CD Pipeline
4:32
Understanding CI/CD Concepts
7:50
The Importance of Automation
9:39
The Magic of Containerization
11:40
GitHub Actions Overview
14:31
YAML in GitHub Actions
30:27
Setting Up a Workflow
37:00
Building the Web App
39:24
Deploying to GitHub Pages
42:30
Transitioning to Automation
48:17
The Future of Deployment
1:10:28
Moving to CMS Mode
1:12:12
Conclusion and Sign Off
Long Summary
In this episode of Programming by Stealth, I am thrilled to take you through installment 176, where we delve deep into the intricacies of GitHub Pages, continuous integration, and deployment automation. After a philosophical discussion surrounding content management systems in our previous episode, we’re ready to roll up our sleeves and get practical with GitHub Pages.
We begin by revisiting our journey through web app development, which we started in earlier episodes. Our goal is to publish a web app using GitHub Pages, and I emphasize that this episode will be highly self-contained. At its core, we’ll deploy an application that we previously bundled using Webpack, intertwining our learnings from installations 138 and 139.
The episode kicks off with a brief recap of our previous key concepts related to CI/CD—continuously integrating and deploying updates to our applications. We will apply these principles as we automate our deployment process, allowing us to push updates to our web app directly to the internet without extraneous steps. I clarify that in the context of GitHub Actions, our aim is to create a workflow that integrates our main branch updates with the deployment of our web app to GitHub Pages.
To set the stage, we teach how to use GitHub Actions to automate the deployment of our project. We carefully outline the process, beginning with creating our repository and cloning it locally. I guide you through the steps of moving files around, ensuring we understand the importance of .gitignore when working with GitHub Pages. We utilize various essential tools like Node.js and Webpack seamlessly throughout the deployment process.
One of the key highlights of this episode is demonstrating how GitHub Actions works by creating a YAML workflow file that defines our deployment settings and jobs clearly. Each job and step are meticulously defined, covering aspects such as checking out the code, setting up the Node environment, and executing terminal commands for building the web app. Additionally, we explore how artifacts work in GitHub Actions, creating a transparent process for the deployment of our built app.
As we progress, I detail the transition from manual deployment to automated deployment using GitHub Actions. The process allows us to define each action's requirements without getting bogged down in the specifics, thanks to GitHub’s effective use of declarative syntax in YAML. We even utilize some pre-built actions from the GitHub marketplace, emphasizing their importance in reducing complexity and enhancing efficiency for our workflow.
We conclude the episode with a successful demonstration of our automated process where the output seamlessly becomes available on the internet without the need for any human intervention beyond committing our source code. I further explain the implications of this automation, which ultimately enhance the practicality of deploying applications.
In closing, this episode not only reconnects us with our web app journey but also marks a significant milestone as we put our newfound skills into practice, setting the stage for future explorations into content management systems and more advanced uses of GitHub Pages. The journey doesn't stop here as we continue to build upon our knowledge and skills, transitioning smoothly into upcoming topics that will enhance our programming endeavors.
We begin by revisiting our journey through web app development, which we started in earlier episodes. Our goal is to publish a web app using GitHub Pages, and I emphasize that this episode will be highly self-contained. At its core, we’ll deploy an application that we previously bundled using Webpack, intertwining our learnings from installations 138 and 139.
The episode kicks off with a brief recap of our previous key concepts related to CI/CD—continuously integrating and deploying updates to our applications. We will apply these principles as we automate our deployment process, allowing us to push updates to our web app directly to the internet without extraneous steps. I clarify that in the context of GitHub Actions, our aim is to create a workflow that integrates our main branch updates with the deployment of our web app to GitHub Pages.
To set the stage, we teach how to use GitHub Actions to automate the deployment of our project. We carefully outline the process, beginning with creating our repository and cloning it locally. I guide you through the steps of moving files around, ensuring we understand the importance of .gitignore when working with GitHub Pages. We utilize various essential tools like Node.js and Webpack seamlessly throughout the deployment process.
One of the key highlights of this episode is demonstrating how GitHub Actions works by creating a YAML workflow file that defines our deployment settings and jobs clearly. Each job and step are meticulously defined, covering aspects such as checking out the code, setting up the Node environment, and executing terminal commands for building the web app. Additionally, we explore how artifacts work in GitHub Actions, creating a transparent process for the deployment of our built app.
As we progress, I detail the transition from manual deployment to automated deployment using GitHub Actions. The process allows us to define each action's requirements without getting bogged down in the specifics, thanks to GitHub’s effective use of declarative syntax in YAML. We even utilize some pre-built actions from the GitHub marketplace, emphasizing their importance in reducing complexity and enhancing efficiency for our workflow.
We conclude the episode with a successful demonstration of our automated process where the output seamlessly becomes available on the internet without the need for any human intervention beyond committing our source code. I further explain the implications of this automation, which ultimately enhance the practicality of deploying applications.
In closing, this episode not only reconnects us with our web app journey but also marks a significant milestone as we put our newfound skills into practice, setting the stage for future explorations into content management systems and more advanced uses of GitHub Pages. The journey doesn't stop here as we continue to build upon our knowledge and skills, transitioning smoothly into upcoming topics that will enhance our programming endeavors.
Brief Summary
In this episode of Programming by Stealth, we explore GitHub Pages, continuous integration, and deployment automation in installment 176. We aim to deploy a web app while revisiting key CI/CD concepts. The episode focuses on automating the deployment process using GitHub Actions, including creating a YAML workflow for deployment settings and managing files with .gitignore.
We demonstrate the automated process that seamlessly makes our app available online. This practical session not only reinforces our web app journey but also sets the stage for future explorations into content management systems and advanced GitHub Pages usage.
We demonstrate the automated process that seamlessly makes our app available online. This practical session not only reinforces our web app journey but also sets the stage for future explorations into content management systems and advanced GitHub Pages usage.
Tags
Programming by Stealth
GitHub Pages
continuous integration
deployment automation
episode 176
web app
CI/CD concepts
GitHub Actions
YAML workflow
gitignore
Transcript
[0:00]Music
[0:07]Well, it's that time of the week again. It's time for Programming by Stealth,
[0:14]
Introduction to GitHub Pages
[0:10]and this is installment 176, recorded February 15th, 2025. And I'm your host, Alison Sheridan. And of course, I am joined by your fabulous co-host, Bart Bouchotts. How are you doing today, Bart?
[0:21]I'm not going to go into the details. I'm here. I'm fine.
[0:26]Well, we're ready to have fun from a nerd perspective, at least, right?
[0:28]Yes, we are. So we had a great big teaser installment last time. We talked all about GitHub pages, and I tried to whet your appetite. We had a philosophical discussion on content management systems. But we're actually going to start to do some real work with GitHub Pages this time. And this is a very self-contained installment. So I think I said something like it'll be 10% GitHub Pages for deploying apps and then 90% as a content management system. All of the app stuff is today. So this is like a little standalone episode-ish. except for i don't think
[1:12]
Revisiting Web Apps Journey
[1:08]It's we're not eating a giant elephant here i was able to go through pretty pretty quickly.
[1:12]Yeah so we're kind of closing a circle that i left dangling a long time ago a long time ago so before we detoured into developer type tools like git and stuff we had been working on web apps and for most of this series that was it right that was the stealth part of me teaching you programming was we did some html which isn't really programming we did some css which isn't really programming and then we did some javascript which is real programming and we built up towards building a web app and then we finished in installment 138 by having webpack bundle our html javascript and css web app that was making use of cool third-party tools like jQuery, Bootstrap, and Mustache, and then we sort of, I think we literally ended with, and publishing this to the internet is an exercise for the reader, and then we just sort it off. Right?
[2:09]Actually, it might even be PPS 139, because that was part two.
[2:13]Well, the 139 is bundling a library, the 138 was bundling an app.
[2:18]It says bundling a web app site. Okay.
[2:20]Okay, so it was part one between those two.
[2:23]For anybody who's keeping track, that was September of 2022. I hope you've been holding your breath. Because now here's how to actually do what he said. We leave it for the student.
[2:34]Yeah. So I think we went on a fun place in between. You know, we learned about all sorts of software development tools to sort of take your app to the next level with stuff like ESLint and NPM, Node.js, JS.doc, Mermaid. I've forgotten we've done Mermaid. You have more fun with that than I do. We did Jest, we did Webpack, and then we got very adjacent. We did Bash and Shema and Git, YAML, JQ. We even did some software engineering with MVC.
[3:09]
Entering the CI/CD Pipeline
[3:09]But now we're finally coming back to where we were in 2022.
[3:13]And that doesn't even count the tidbits.
[3:18]True, yeah. We've been on quite the journey, quite the journey. Anyway we are going to come right back around and we're now going to publish a web app like we learned about way back in 138 and we're going to do it to the real internet without costing you any money and we're going to do it manually first and then we're going to automate it and actually using some of this ci cd stuff i've been dropping into the last couple of installments in preparation for this i've sort of been dropped whenever i get a chance i drop it in and i think i need to say to Alistair Jenks, who posted in the Slack, or was it an email? Either way, Alistair got in touch to say that I keep on saying that the D in CICD is development. It's deployment. Deployment, deployment, deployment. I keep saying it wrong.
[4:05]Oh, and that's actually, I think that'll be cemented in what you're going to teach us, because the word deploy is going to be coming out continuously. See what I did there?
[4:15]Excellent. So thank you, Alistair. And yes, I have been getting it wrong i don't know why it's stuck in my head wrong So yes, we are going to use a CICD automation to automatically update our real
[4:32]
Understanding CI/CD Concepts
[4:28]web app on the actual internet every time we push code to main. And it's going to be published using GitHub pages. So that is today's episode, I guess, or installment, I think we call these.
[4:41]So what is this CICD thing I keep getting wrong? Um so at a it's continuous integration continuous development the integration part continuous deployment oh see again it's in my head wrong so the theory is right philosophically if you're doing software in the cicd sort of a way you're thinking in terms of small incremental changes constantly. And so the continuous integration is that you're constantly integrating everyone's changes. So you might have a team with 50 people and they're all working on a little bit of the code. Well, with a CICD pipeline, every time any of them push into the main branch, their work gets integrated together. It then gets deployed to a test system in the real world. Instantly, everyone tests it. And then whenever a manager is like, oh yeah, I'm good, then they push it to main, and then it gets deployed to the real world. And so you might notice that, in fact, a site like GitHub, it tends to change very, very slowly. If you look at a screenshot from three years ago, there's lots of things have changed. But month to month to month, do you notice much change? No. But it must be, because otherwise your three years ago screenshot would still be right.
[6:05]But you don't hear them say, look, GitHub 17.6 is out.
[6:11]Right, but under the hood, they have versions and they are doing all of this. And they are doing lots and lots of little changes. For all I know, it's every Friday afternoon, every Tuesday morning. Who knows what their schedule is? But that's the CICD mindset. You're just constantly putting out codes all the time. And for that to work the process of publishing a change can't be laborious it can't be a big chore to release a new version because you're doing it so often and the answer is automation so in CICD land everyone uses the word pipeline so your code gets shoved into one end of the pipeline some automation happens and then something falls out the other end of the pipeline and there's something maybe something different depending on where you are in the development process so you could use a CICD pipeline to take everyone's commit and run it through a linter or a test suite and email everyone and go well or actually just email the person who made the change because Git knows who made the change you could email every developer when they push to say thanks very much but actually you've made these three mistakes you need to fix that in the linting before we're going to let this go into production. Or congratulations, all tests passed, no regression bugs, yay. Right? So you know, you know, so you have an automated of that sort.
[7:34]It could actually do that.
[7:34]Yeah, absolutely. And the other thing you would do in the real world is automatically deploy it to some sort of test or staging server where you could really see what you've done in action before you hit the scary button and allow the pipeline
[7:50]
The Importance of Automation
[7:47]to take it into the real world on the actual public internet. But for today for us you know we're we're just playing here we're going to just do the last of those things every time you push to main and again we've mentioned that if you're doing work you work on a temporary branch and then when you're happy you merge that branch into main so it's not a you know it's not complete chaos but every time you push to main we're going to push straight to the internet that that's what we're going to do but
[8:18]It's a okay by the way i've just I've just done my first branching recently. Well, successful branching. I know years ago I did a branch, and I stayed on that branch for so long that I was never able to merge it back in, and you had to help me just...
[8:33]Did we rename it back to Maine? Yeah. Did we delete the other one and just rename the new one?
[8:39]Yeah, because it'd been like two years I'd been on the branch.
[8:42]Yeah, that's not merging back.
[8:44]No, no.
[8:46]If you're curious about the philosophy of CICD, the wikipedia article is actually quite good so that's linked in the show notes So generally speaking, a code management platform like, say, GitHub is going to have some sort of support for CICD because source control is a vital part of the CICD mindset. Imagine that mindset of push early and push off and without source control. Chaos, right? Never work. So all of these tools have a form of CICD. And in GitHub world, it's called GitHub Actions. That's their implementation of this concept. And so this blew my mind when I first learned about it. But what actually happens when you run a GitHub action is an entire virtual machine gets created.
[9:39]
The Magic of Containerization
[9:40]Your code for your pipeline gets put into that VM. The VM runs your pipeline and then it's destroyed. Every single time.
[9:52]That is bananas. that is that is that's nuts yeah how can it do it that quickly that's.
[10:00]The magic of containerization so containerization is this half virtualization where you don't duplicate the operating system you effectively share it so there's one linux kernel but it's actually the same kernel inside like 5 000 vms and so you can start them and stop them really quickly because they're sharing 90 percent of their stuff and the only thing that's different than the vm is your little piece it's amazing technology containerization is magic
[10:28]I've got to throw in an anecdote here when i was working in it now it's been more than 11 years since i left my my jobby job but there was a point where we were trying to justify building up a virtual machine scenario for our customers because it was taking us four months to buy them a workstation to use as a test machine. And we're like, you guys, let me just show you what you can do on Amazon Web Services right now. Okay, ready? Watch. Bink! Let me pick like three parameters and hit this button. I now have a deployed machine. That's what takes us four months. And they're like, no, this is a process we always find. We can't do it. We're going to have to put it through a committee and everything. I think I retired before we succeeded.
[11:14]Oh, no.
[11:17]Anyway, I'm sure they've done it by now. It's only been another 11 years. I bet they're all over that. Yeah. Yeah. Yeah.
[11:25]Okay, so we're not going to do a giant big deep dive in GitHub Actions, but the documentation is actually really good. So that's linked repeatedly, generously throughout these show notes. I've linked to the docs lots of times.
[11:40]
GitHub Actions Overview
[11:40]And I'm just going to give you a big picture overview of the terminology they use. And it's very sensible, but I'm going to introduce it to you, and then I'm going to use it religiously, because that's what you're going to see in the interface. So within GitHub Actions, what is abstractly a CICD pipeline in GitHub Actions, it's a workflow, which is a pretty good name for an automation. It's a workflow. A workflow contains one or more jobs, and each job defines a sequence of steps. The workflows get triggered by events, which are basically actions on a GitHub repository. So maybe it's a merge or a pull request or a commit. It's some sort of action you do to a GitHub repo. That's your trigger, which starts your event. And then the workflows run on these virtual machines, which are called runners, which is a cool name for them.
[12:39]Bart, all of this makes perfect sense.
[12:41]I know.
[12:42]And those are words I can remember. It's like everything else we seem to learn. It's like, okay, the things that run are called stop. You know, it's always backwards. But yeah, no, I can totally follow this. You've got a workflow. It's got jobs in that. Jobs have to have steps. You've got to trigger it by something. By what? You trigger it by an event. And what are you going to run it on? On a runner. Yeah. And so a runner is like Linux or Windows or even Mac OS, right? Yeah. Whatever it's run on.
[13:10]Yeah, right now on GitHub Actions, you have the choice of Ubuntu Linux, Windows, or Mac OS, which is a pretty good choice. Yeah.
[13:18]What would happen if we picked macOS? That'd be something fun to try.
[13:22]Well, imagine if you're using GitHub to develop a Mac app. That's literally what you're going to be doing. You're going to be using a macOS runner, and you're probably going to have it running an Xcode compile. And that's not going to be free, because when you run GitHub Actions, you get so many seconds per month of execution time. And for what we're doing, the virtual machine is there for like 10 or 15 seconds, and it's finished. If you ask it to build a Mac app, you will get a bill. You will absolutely get a bill.
[13:54]Okay, maybe I won't push that for the runners then. No.
[13:58]So how do you define one of these workflows? Well, I've had many, many motives for sneaking YAML in, what, six months ago or so. I think it was last time when we did YAML. One of them was for front matter and stuff. We're going to spend a lot of time in the next 10 or 15 installments, however long it takes us to do GitHub pages. But another reason is because I knew that they are what make GitHub Actions act.
[14:31]
YAML in GitHub Actions
[14:22]So you define what you want your workflow to do in YAML, which is kind of weird. So you're sort of kind of programming in a markup language. Huh. Because it's a declarative language. So you tell GitHub Actions what you want to happen and it will then go and figure out the mechanics of doing it so what's actually in your GitHub Action is more of a statement of intent so it's more like writing a shopping list and exactly how to make that appear at your house as someone else's problem and so a markup language is actually fine because you're just saying what you want not step by step by step I know we define steps but we define them in a very high level way The detail is not our problem Which is nice
[15:14]Now, before you get into this next part, I want to tell the audience, when you look at the show notes for this, you're going to just be so happy. Bart said he's giving you links everywhere to the documentation, but he's also made beautiful little tables for us to come back to this as a reference manual. If you've got to learn more, sure, you've got the links, but he's got everything to find in these. It's just packaged beautifully. I was really happy reading this part.
[15:39]Oh, thank you. I was thinking of you as I was doing the tables because I started writing in his paragraphs and I was like, oh no, no, no, no.
[15:45]She's going to be all over me.
[15:49]So our YAML file.
[15:50]Thank you, Siri, for joining us. Sorry.
[15:52]Third co-host. Hello, Siri. So our YAML finds contain one single top-level dictionary and everything is a child or a grandchild, whatever, you know, it's all in that dictionary somewhere. And at that top level, you're defining your workflow. And so you have a whole bunch of optional keys, but the important keys are the ones I have here in the first table. The first one is a name. You don't have to give it a name, but if you'd like it to look recognizable in the interface, give it a name because you're going to be looking at the interface and you're going to want to see something that makes sense to you. So take a moment, give it a name. Um, you absolutely have to tell the workflow what its triggers are. Like you have to say on, which is the keyword, and then define some sort of event where it's going to do something, right? A workflow without a trigger doesn't make any sense. It's right.
[16:56]So on is how you tell it, like on push domain.
[16:59]Exactly.
[17:00]On pull request. Exactly.
[17:03]And so we said that our workflow contains one or more jobs. The jobs also get names. So the jobs is a dictionary. So within our top level dictionary, you have a key called jobs. And that is itself another dictionary defining named jobs, depending on how many you want. and if you're wondering because you
[17:26]Might have doing a whole bunch of.
[17:27]Stuff yeah and if you're wondering but a job contains steps why would i need more than one job well the answer is jobs can run in parallel they don't have to but they can so they're little unified sensible pieces and sometimes they run in parallel and sometimes they don't you kind of get to decide but you could say imagine you have a mac app you might have one job that says build this for linux and another job that says build this for mac and another job that says build this for the web they can run in parallel you don't need one then the other then the other so if you do them in three jobs you could just let them all happen in parallel whereas if you did it as one big job you'd be waiting waiting waiting waiting waiting waiting do
[18:16]You have to tell it parallel or in series or is by definition if it's all in one job that's in series and if it's separate jobs then is parallel.
[18:24]No it's much cleverer than that so we're going to see how that's done when we look at the dictionary for each job but it figures it out so this is a declarative language so you don't have to worry your pretty little head about whether or not it can be paralyzed you just define your requirements and it figures it all out it's very clever but we'll see about that in
[18:44]A moment we're not telling it the how we're telling it the.
[18:46]What exactly declarative that's that's the magic here it's a declarative language.
[18:51]Would an example of parallel jobs be what you were talking about before, where I could have a trigger that says on commit to this test server, it's going to run the linter, and I could trigger a message to go back to say, hey, you made these linting mistakes, but I could also at the same time be running a job that's checking to see if it passes the test.
[19:14]Yeah, absolutely.
[19:16]Because those are not dependent on each other, and you're going to need the answer to both anyway. Don't bother fixing your linting problems if you've got garbage code, because you're going to get that in a minute.
[19:25]Exactly, exactly. Yeah, so the only time you have to worry about something happening in series is if there's the dependency. Otherwise, they're going to be in parallel.
[19:35]Okay.
[19:36]You get to define any permissions that the workflow is allowed to have. So the workflow runs as you. So in theory, the workflow could do anything you could do. But maybe you'd actually prefer the code running on someone else's virtual machine to have different permissions to you, if you're, say, a maintainer. Maybe the linter only needs read permission. Does the linter don't really need any more than that so if you want to get clever about this you can really lock down what the automation can do you can make it a read-only automation it's a good idea and then and so
[20:15]Again it's permission this isn't people or accounts having permissions it's the work job.
[20:20]It's the work it's the workflow the whole workflow okay so you set permissions at the workflow level and then you can tune them even more at the job level. And I think you can tune them again at the step level. So you can basically say the whole workflow has these permissions and this job has this subset and this step has this sub-subset. But I don't think you can open it wider than what's provided at the top level, if you get what I mean.
[20:47]That would make sense, yeah.
[20:49]And then env is always a useful thing, the environment. So if you need to have a variable that's available to all of your different jobs and steps, shove it in the environment, and then it will exist everywhere else in your workflow. For simple stuff, the env isn't important, but as soon as you start having things like, is this a beta or is this not, you might set env is beta equals true or something, right? And then all of your steps can have a little segment. If it's a beta, then do this, else do that, right? It's a useful thing to be able to do. So we're going to keep things simple. We are only going to deal with one trigger. So the event we're going to use to trigger our workflow is a push to main. So as far as we're concerned, the on key is a copy paste job. On, which defines one key push, which defines one key branches, which is an array with one element main, which all translates to...
[21:53]You've just said on colon, indented push colon, indented branches, colon, square bracket, quote, main. Yeah. Great. Reading that, that makes sense. What am I looking at? Is that a whole workflow? Is that just the job?
[22:06]That's just the on key within the workflows dictionary.
[22:13]Got you. Okay.
[22:15]So the name, obviously, we know what to do. The on is what I've just described there. The jobs, we're going to look at in a moment. And I don't think we need to talk about permissions around today. So the next one then is the jobs. So for each job gets its own little dictionary. Quite a big dictionary, actually. It gets its own dictionary. And again, it has a bunch of keys. And this isn't a full set of all the keys that can go into a job. This is the important ones. again give it a name it will help you no end in the github interface if things have nice names right you'll you'll be happy now you asked about how do we handle parallelism this is what the needs keyword is for if you have a job that needs another one to have finished first you say needs and then you give a list of all of the ones that you want finished before you can run.
[23:12]Oh, okay. And so that's all you have to do.
[23:16]And then GitHub itself figures out, okay, so this one needs this and this one needs this and this one needs this. How much can I parallelize? And it figures it all out for you. And then it defines the structure and it builds the tree of I'm going to do these two in parallel and then this one in series. It does it all for you. All you do is say what you need and it figures out the rest.
[23:38]The runs on is how you tell it whether you'd like a Linux or a Windows or a macOS. The steps is an array of dictionaries that define the steps. So we're going to look at those in detail in a minute. And then again, we get to set permissions and environment at the job level. So a lot of this stuff is nested, right? We have permissions and environment at the top level of the workflow. We can also add some at the job level. and now we're going to take a step forward i'm going to look into actually before we take a look in a name is obvious the needs is just the names of the other jobs the runs on we're going to be very simple we're keeping things cheap runs on colon ubuntu dash latest which means that we don't have to update our workflow every time there's a new release of ubuntu we're just going to live on the edge and say we're going to assume our code is going to keep working forever just stick it on ubuntu latest it'll be fine in the real world you might be more assertive and say you want it on ubuntu whatever the current version of ubuntu is so the current lts probably but you know that's we're going to keep it easy
[24:52]So the last dictionary we're going to look at is the dictionary that defines each step. And again, not a full list of keys, but nonetheless, this is, you know, this is a list of the important ones. Again, give it a name. Everything should have nice human names and then everything will just make more sense. So you can then use sort of combinations of different keys here, depending on what you're trying to do. So one of the keys at your disposal is the run key, which literally lets you give terminal commands. If you're using Ubuntu, they're bash commands. If you're using macOS, they're going to be ZSH. And if you're using a Windows VM, I would hope they're PowerShell. Ooh, unless they're DOS. I don't know. I've never tried a Windows machine. but anyway the run for us is a bash terminal so we can literally put our terminal command straight into the run you can pass um sort of hang on a sec uh yeah if you want to run more than one command you can actually give it a multi-line string and each line in the string is the next command so you can literally do a full script inside the run the
[26:15]Is that the way you would do it.
[26:16]It's the way we seems
[26:18]Like that'd be real messy inside a yaml.
[26:22]File i'd do it for two or three otherwise i'd write a shell script in the actual repository and i would use run to say run my script which is sitting in the util folder in the repository say
[26:38]That one more time.
[26:38]So if i needed to do something complicated i write a script and i'd have it in the actual repo and then my run commands would more sense to me yeah yeah
[26:50]Yeah i mean i can see if it's you know rename blah okay i'll leave that in there but if it's something takes and something i'd want to be able to manage in git.
[27:01]Exactly now these yaml files are in git i think i had meant to say it Oh no, I did forget to say it. These YAML files get saved as a special folder, .github forward slash workflows. So that's where those YAML files are. So they are in Git too. Of course they are. Everything in Git is in Git. Sorry, everything on GitHub is in Git. That's how GitHub works.
[27:26]Okay, so run, let's just run a terminal command. Uses is then an alternative. So you can't use run and uses in the same step, right? You're either giving it a terminal command or you're using the uses keyword to say, run this action from GitHub's marketplace. And so GitHub has this marketplace that are basically pre-written, effectively, their scripts. I think they're written in Python under the hood. So they're little magic things that you just call by name. You pass them arguments with the with keyword, and they will do something. So if you need to do something really common, the marketplace is just going to have a pre-written action for you. So there's an action to check out the latest version of my code. There's an action to install npm in my virtual machine there's an action to install say ruby in my virtual machine if you were writing a ruby app there would be an action to install the c compiler if you were building a c app so these actions are in the marketplace and there's hundreds of them so with the users keyword you just point it at an action and then the with keyword is used to give it the arguments you
[28:51]So I'm muting a lot, by the way, because there's a chainsaw outside. Oh, lovely.
[28:54]But it's good because they're cutting down a tree.
[28:58]No, no, I'm sorry. We offered them ours, but they're actually cutting down, trimming back a tree that's been blocking our solar panel. So we're happy about it. But my question is, you say on this, so this is steps we're talking about. We've got run and we've, I'm sorry. Yeah, we've got run and we've got uses. And you're very specific. You say use run or uses, but not both. Does that mean that you would have to create a different step if you needed to do a shell command, and then a different step if you were going to use one of these magic things from the marketplace?
[29:33]Correct. And so remember that steps is an array that contains multiple instances of this little dictionary we're describing here. So in our example, we're going to have one step that is a uses and then another step that is a run and they're all within the same job so a job can have many steps some of which will be run some of which will be uses but no one step can be both
[30:02]Okay okay seems like that'd be limiting but probably apparently.
[30:05]Not no you just do it next right if you need to do both then you have two steps you know as many steps as you like all right and again we have the env if we want to pass some variables into whatever it is we're doing the more advanced you get the more useful
[30:27]
Setting Up a Workflow
[30:21]Yes i am he's saying e and i'm trying to say it when you're not talking env.
[30:27]Correct okay so we now come to a worked example and these are a little bit different to what we normally do because you're gonna have to set up a repository in real GitHub and you're going to be publishing stuff to the real internet. So this isn't very real time. So me and Alison have broken the mold.
[30:51]Yeah, so we've talked about this a couple of times. The show goes much better if I've read the show notes ahead of time and if I've worked through the examples. And this was a perfect example of it where there's going to be a lot of steps where you'd be sitting here listening to me typing things and waiting for things to happen. So instead, I did it ahead of time, but I just did it a few minutes ago, so it's fresh in my mind and I've got all my questions ready as we go through this.
[31:16]Yes, so while I was eating dinner, Alison was doing these worked examples and now we're recording about them. But in real time, these are slower than what we'd normally do because normally Alison's running it as we're recording and she doesn't have 500 hours of editing afterwards to edit out all the pauses because usually it's really quick, right? It happens straight away, but this isn't that. So be prepared.
[31:37]Yeah, we talked about, we actually, I suggested, okay, well, we could do it where as long as we're dead silence while I'm doing a step, then I can find those spots in the recording and cut them all out and part's like, really, you want to do that?
[31:50]I wasn't going to say. Anyway, yes. So Alison has done this. So we're both going from memory here. But what we're going to do is we're going to use GitHub Pages to publish a web app to the real internet. But we're not going to automate it. We're going to do it the manual way. And the reason we're going to do that is because then we get to know what we want to automate. Right. So we're going to have a proven set of steps or a proven set of jobs. And we're going to see what they're like. And then capture them Turn them into YAML And then do them automagically So I was too lazy to write a whole new web app. Normally I get very carried away and I spend three quarters of the time writing the show notes making silly examples that take three minutes of airtime.
[32:36]With emoji.
[32:37]With emoji, often related to Christmas for some reason. I didn't do any of that. I went back to installment 138, which was the last time we did a web app. And I took the last worked example from 138 and that's the code we're going to deploy. It's really boring. It's a web app that just uses our various technologies to do something really boring and show a message on screen. But it is using Bootstrap, it is using jQuery, and it is using Mustache. And it's all built with Webpack. Correct. So Webpack is bundling it all together. So it is a perfect example. It's just not very exciting.
[33:15]So we have a brand new zip file that's PBS 176, but if you look inside it, it's actually PBS 138.
[33:21]Yeah, with one or two little additions, but very, very little has changed. Very little. So if we teleport our minds back to 2022, the way we were working is that our actual code was in a folder called src, which is a convention used very often in software engineering. And our published web app was being outputted to the docs folder by Webpack. And our configuration defining our various dependencies jquery and all that kind of stuff is in the standard node package which is package.json so they're the three most important things in that zip file your source the docs which we'll be building and the package.json so the first thing we're going to do is we're going to go to github and we're going to make ourselves a new repository and then we're going to clone it locally onto our mac or our linux machine whatever you're using like you have done every other time you've been playing along in the git series and you're going to open a terminal in that newly cloned copy of your empty repo
[34:36]Then you're going to take the zip file extract all the content copy it into that folder and then rename one file. So to stop it being invisible to you, I named the file underscore git ignore. You should now rename that to dot git ignore. It will vanish from the finder but it's in there and it's going to tell git to ignore some stuff it should ignore like the folders and stuff you make when you run the npm commands.
[35:08]Just for the audience, you have to do that from the terminal with the move command that the finder won't let you. It yells at you and goes, no, dot files are specific, are very important. You shouldn't be touching those things.
[35:20]I've done something to my Mac that it doesn't do that, but I don't know how or when.
[35:26]Well, I was going to be in the terminal anyway, and I'm in the terminal all the time now, Bart, so I'm perfectly comfortable there, so I just moved it.
[35:33]I think I know. i think i renamed it from inside xcode or not xcode uh vs code vs
[35:42]Code vs code oh that might.
[35:44]Be yeah it didn't shout at me anyway i renamed it without getting shouted i'm not entirely sure how i didn't get shouted at okay okay then we are going to what do i say in the show notes uh do i say to commit i don't think i do oh no sorry i do i think with the initial code commit so I guess I do. So commit the code. So at this point, we have our source, but we haven't actually built a web app. So the content of docs at this point in time is a placeholder. So now we're going to manually build the app.
[36:20]Now, reminder, I think you sort of said this, but after we build the app with Webpack, that's when the docs folder gets populated. It's empty until we're going to do that. So we need to do the webpack thing.
[36:32]Yes. So you need to make sure you have the latest or a current version of Node.js. The LTS is fine, the long-term support. Or you can live on the bleeding edge and get the very latest version. But either way, have something vaguely current and you'll be good. We are going to dig back deep in our memories here. and we're going to use the npm ci command to initialize npm in our folder.
[37:00]
Building the Web App
[37:00]And that stands for clean install. So package.json defines a minimum version for all of your dependencies. But over time, how that minimum version gets translated into the actual installed files changes. It could change day-to-day, which would be chaos. So that's why when you first run, say, if you were to run npm install, not CI, but install, it will get the very latest version of every dependency, and it will write what it's done to the file package-lock.json.
[37:44]We're doing the opposite. We're not asking it to figure out what the latest versions are. We wanted to take package-lock.json and duplicate it. So do exactly what was done when I wrote the code. That's what CI does. So install updates package-lock. CI just reads package-lock.
[38:07]Oh, that's interesting. I didn't catch that subtlety the first time you taught us about that.
[38:12]Yeah. And when you're doing CI, CD, you're always doing a CI because you want your builds to be repeatable. You want it to always happen the same. And that's what you get with NPM CI.
[38:25]Okay, but CI and CI are not the same in the sentence you just said. NPM CI is clean install and the CI is continuous integration.
[38:34]Yeah, that one I don't get wrong. The CD, no, forget it. I'm not even going to say it. Okay. Okay. So at this point, we have our node environment ready to go. That will have downloaded jQuery and Mustache and Bootstap and saved them all into our folder. So now we're ready to build our web app with Webpack. And the package.json file defines all the details for how to do that. So all we have to do is run npm run build, and it will build our web app and put it into the docs folder. And it's going to do that using webpack.config.js, and it's going to read the source from the src folder, and it's going to write it all in index.html in the docs folder.
[39:24]
Deploying to GitHub Pages
[39:24]If you open that file in your browser, you can see our very boring web app that says hello jQuery world, which is exactly how it looked way back in 2022.
[39:38]And it was exciting. Oh, riveting. It was very exciting. Then you're going to...
[39:42]Sorry, Allison.
[39:43]It says, hello, jQuery world.
[39:45]Ah, yes. So you're going to push that to GitHub. Sorry, push that up to GitHub. So commit and push it up to GitHub. And now you're going to go to GitHub, and we're going to put this on the internet. So we've built our app. It's ready to go. It's sitting in the docs folder, so let's publish it to the internet. So the way you do that is you go to GitHub, you go to your repo, you go to settings, and then you choose in the sidebar, pages. Then you have to tell GitHub pages what, right? What is the source of this website you'd like to put on the internet? And you're going to choose deploy from a branch. You're going to say your main branch, and then it's going to give you a second dropdown, which is all the folders that exist in your main branch. And you're going to say the docs folder, please. And you're going to hit save.
[40:31]So we're telling it the docs folder because that's what we just built with our webpack.
[40:36]Correct. Correct. So if we had a different naming convention, we would pick a different folder. But this is our naming convention, so that's what we're doing.
[40:45]Now, what I want to bring up here is what's magical, in case people have forgotten from two and a half years ago, is that because this was all built with Webpack, the app is fully contained. This is a pile of code that does everything in this nice little container, and it doesn't have dependencies that anybody has to run or anything like that. So that's going to go in and run, and it's the docs version that can do that. If you give it the stuff from source, it's running all of that stuff. Is that a good way to describe it?
[41:18]Yeah, basically, all of those dependencies that we used to have reaching out to CDN URLs and stuff, they're now all contained in indexed at HTML. They've all just been bundled, which is why Webpack is called the bundler. And it's now perfectly self-contained, and every CDN in the world could explode or could get filled with malware, and our app wouldn't care because it has its own copy of jQuery and of Mustache all safe inside it, all safely bundled in.
[41:48]Is it a true statement that you need to have a bundled thing like app like this in order to do a GitHub page?
[41:55]No, you could say script source equals HTTPS colon slash slash whatever and it would work fine but then you're at the mercy of whatever URL you put in the script tag. It will be brittle. You could make it work. You don't want to.
[42:13]So you can have a complicated web app that's got all the files and not all bundled together in a GitHub page? I thought since it was a static site generator, it needed to be bundled.
[42:30]
Transitioning to Automation
[42:25]As long as it doesn't rely on anything server-side, you could serve it. That's a really complicated question to answer in detail. Bill, the very, very hand-waving answer is yes, but don't.
[42:40]Okay.
[42:42]So there's a really good reason someone invented GitHub Pages. It was solving a real problem. It's a problem we want solved. We don't want to work around it the hard way.
[42:52]I do like this, though, because with my tiny little web apps, all this bundling stuff has been a little bit of overkill. I'm just updating a simple web page with some buttons, and it does a little bit of math. And so I'm carrying this burden of all this complexity to do that. But now I'm getting the advantages of it is now when I put it up on the web, it's just this, and it's snappy. It's got it all right there together.
[43:17]Yeah, and there's no more work in bundling a giant app or a tiny app. It's the same overhead. So for you, it might make up 20% of your mental work. But as you start writing bigger and bigger apps, that same work becomes 20%, 15%, 10%, 5%, 2%, you know. insignificant but
[43:38]I i don't curse it anymore because that part's already done.
[43:41]Exactly and it's very it's very static it just once you have once you have webpack configured it just is it just sits there and does this thing yeah yeah and you get on with life you know okay so we've told it deploy from main take the docs folder we've hit save the moment you hit save behind the scenes a little virtual machine came to life, your entire repo was cloned into that virtual machine, and the content of your docs folder was taken out of the clone, put onto something called an artifact that we don't really care about right now, and then another job within the same workflow took that artifact and put it on the real internet.
[44:30]All of that happened as soon as you hit that save button. Depending on how quick you are at clicking. I know. Depending on how quick you are at clicking, you may or may not catch it in the action. So what you're going to do now after you've hit save is choose actions from the button bar across the top of your repo. So it's a peer with settings and stuff. And that's going to take you to all of the GitHub actions on your current repository. And you will see one called pages build and deployment and that one is what bursts into life when you hit save and depending on how quick you are you might see it in the queued status if you're very very quick you might see it in the in progress status if you're fairly quick or more probably a green tick which means i've done i've done a bit if
[45:24]It took 41 seconds for mine to go from queued to progress to completed.
[45:30]Isn't that amazing? An entire virtual machine came to life, lived its entire existence, and went away all in that time.
[45:38]We thank it for its service.
[45:39]Exactly. So if you click on the workflow's name, you're going to see details of that specific run of the workflow. And the deploy step will show you the URL where your app is now on the internet. It will be github.io actually no, it'll be your gitusername.github.io forward slash repository name if memory serves. It'll be something like that. But it's there for you. That's right. Okay, so open that in your browser.
[46:11]Oh, so you can click it and see it.
[46:12]You can click it and see it or right click, open a new tab because I don't want to lose me github. But you know, yeah, you can have a look and there you are. It's exactly the same as it was locally, but now it's on the internet and you can share it with all your friends. Congratulations. So that was a manual job, right? This will work, right? This works. If you run your web app like this, you just have to remember every time I want to update my app, I need to check it out, run Webpack locally, commit again, and then the new source folder will exist. And then as soon as I push that commit, it'll end up on the internet because the workflow will happen again and it'll go up to the internet. And so that is workable. But you're having to remember to do the npm run build on your local machine and then commit the output of that build and then it can go on the internet. But we're going to do now.
[47:12]So you have to, when you commit doing it manually, you have to commit not just your source folder, but also the docs folder?
[47:21]Correct, because that's how it's getting to the internet. You're just telling GitHub pages, is take the docs folder and make it be the web page. So you have to update the docs folder for the web page to update. So it's a manual process. You are building and then you are pushing new content in that folder. We can do better. We can use GitHub Actions to automate that deployment so that all we have to do is manage our SRC folder and the docs folder will happen automatically. You can add it to your gitignore file So you can build locally to test. And then when you're happy, you push only your source. And then that same thing happens in the cloud. And the docs folder never appears in your repo because it's not needed in your repo. It's needed on the internet. So the GitHub action will create the docs folder and publish it,
[48:17]
The Future of Deployment
[48:16]but it will never save it. It just goes to the internet through an artifact. fact.
[48:21]I'm not sure that would be the best way to go, though, Bart. So, right now, I'm working on my web app, and I've got it on two different Macs. Sure. If I...
[48:33]Well, yeah, you do NPM CI will make sure your two Macs are identical and that the automation in the cloud is also identical. That's why NPM CI is so important because you're using that.
[48:46]How often do I have to NPM CI? Every time I want to play on that computer?
[48:51]Every time that you start fresh on the new computer or when you add a new dependency. So imagine that you don't need Mustache for six months, and then you decide on month seven, ooh, I think I'll use Mustache. You're going to have to run npmci once in every machine after adding Mustache.
[49:11]So it's whenever you mess with your package.json?
[49:14]Yes.
[49:16]Okay, so if I put my docs, I'm working on my MacBook Air, and I put my docs folder in my gitignore, but I'm working locally, I'm running npm build constantly and mess it around locally. But then when I push it up to GitHub, when I commit it to GitHub, it doesn't grab the docs folder, but it creates it automatically through the GitHub action that we're going to learn how to do. And then when the other Mac gets it down, it's not going to get... Is it going to get a docs folder?
[49:45]No, because it's not in the repository at all. It's not going to get the docs folder. You're going to run npm-ci, npm-run-build.
[49:54]You said I don't have to run npm-ci every time.
[49:57]Okay, but you do have to run NPM run build.
[49:59]In the morning and the afternoon, I'm going back and forth. I do have to NPM run build.
[50:03]Yeah, but you were saying that you and Helma have gone a step further and you have your NPM run build happening automatically as well, which is also cool, and you can do that totally.
[50:13]Yeah, by the way, that's with NPM run watch. Yes. And setting it up in your package.json correctly. I didn't know that I could do it with NPM CI this morning when I did it, though, with Helma. Is I typed it in manually in there. Okay.
[50:30]Okay, so we're now going to automate what we did manually. So to do this, we are going to use a bunch of the officially verified standard actions. I forgot to tell people to be careful in the marketplace, didn't I? I didn't have my cybersecurity hat on. Actually, no.
[50:50]Oh, no, you're just about to tell us.
[50:51]I'm about to put it on. I've just looked ahead of my show notes. Yeah, okay. And you might say it somewhere. So the GitHub marketplace is like a plugin store, like if you go get plugins for your browser. In theory, there's a bit of due diligence and there's some automatic scanners and really obvious malware is not going to be in there. But I wouldn't bet the house on that. The baddies are very keen to sneak malware into those standard actions. But don't worry. you can stick to the walled garden they are verified creators which are basically github themselves and their partners so there's a filter uh that's called uh always at the fill the buy filter creators to verified creators so the filter is called buy where in the marketplace am
[51:46]I doing in the market i'm not in the marketplace i don't i don't know where the marketplace is.
[51:50]Okay so if you scroll up in the show notes to where we talk about users we say that you can get the actions in the marketplace okay
[51:58]But we're about to do it and you don't talk about how to go get them from the marketplace are you just saying these are ones that you.
[52:05]You put them in your used okay so in your code they're just a name it's a repository forward slash a name so if you're going to if you don't know that the action for checkout is whatever we're about to see, you can find all the names you could use in the marketplace. And so if you're looking for something, I'll sneak the description in where it makes sense. I have noted that you would like some more detail and I will sneak it in.
[52:36]Okay.
[52:38]Okay, right. Where were we? So we are going to use some standard actions and we're going to use the run version of the step dictionary. So we're going to do uses and run. Okay, so the first thing we are going to do is to update our GitHub Pages settings to say use an action as opposed to the default workflow. So by default it just publishes a folder. We're going to say don't do that, use this action instead. So you go back into GitHub, you go back to the GitHub Pages settings and the source drop down, you change it from branch to GitHub Actions. And then you take the option to create your own action.
[53:26]And then you'll get a little editor pops up and it will ask you to name a .yaml file and then put in some content. So I suggest giving it a name like deploy-app.yaml, but call it whatever you like. Waffles, pancakes, something. Something sensible will be good. And then you're going to paste in the YAML code in the show notes. And so this is the YAML code for a GitHub Actions workflow. So remember that I said, always give your workflow a name. So the first key in our dictionary is name, build with webpack and publish to GitHub pages. That is a nice human-friendly name. We said that our on key would always be on push branches main. In other words, whenever someone pushes to main, we run this workflow. And then we define our list of jobs. and so our first job is named build and our first job gets only the permission to read the content of my repo so in how come because I'm saying permissions content read
[54:38]No I'm saying how come.
[54:40]Well because we are going to clone our code into this virtual machine so in order to clone our code we have to be able to read our code
[54:47]But we don't need to have to be able to write it.
[54:50]To it because we're not it's
[54:51]Going to be writing no it's going to be writing stuff into the docs folder.
[54:55]No it's going to be creating what we used to have in the docs folder in github pages the output is not our repository it's the internet so
[55:07]There will be there will be no docs.
[55:09]Folder there will be no docs folder oh okay we're we're making the web page and putting on the internet So it goes to the internet. It doesn't go into the repository. It goes to the internet, which is where you want it. All right. So it just needs read-only access, so it's safer, right? This automation can't edit our code. It can only read our code. That's a good safety feature. So permissions, content, read. Runs on Ubuntu-latest, right? We said we'd always do that. Our job then contains a bunch of steps. So this is a YAML array. So the first step is named checkout code and it uses actions forward slash checkout at v4. Now, remember I said this is where the marketplace comes in. How do I know what magic name I can type there? The answer is you search the marketplace and it will tell you the name. So the marketplace...
[56:11]Where's the marketplace?
[56:12]Okay, so scroll up to the pretty table you gave me search credit for and look at the key uses. And then it says listings of predefined actions in the GitHub marketplace as the last link in the description.
[56:26]Okay. How would I know that if I wasn't reading your show notes?
[56:32]In the sidebar next to the big empty window, they have some helpful resources. And one of them in there is a search box that will get you there too. That's how I found the marketplace. I don't remember the exact detail, but the big empty box on the GitHub screen does actually have a useful sidebar.
[56:49]Okay, so how did I know what I wanted? I wanted to check out code, so you just type in checkout?
[56:55]Yeah. And remember, they set the by to verified creators.
[57:00]Oh, by all creators. No, verified creators. Okay, now I'm looking at it. I got you. And there's one.
[57:06]Yeah. It's a standard thing. And lo and behold, it's by GitHub.
[57:14]Uses, and it shows us uses actions, check out v4. But it also has a whole bunch of comments. That's just telling us what else it's going to do.
[57:22]Yeah. I mean, you can read more if you like, but we just... The great thing about using a pre-made step is that all you really need is the magic name, right? Once it's the one you want, you just give it the magic name.
[57:34]So what happens when they go to v5?
[57:36]Well, unless you proactively update your code, your workflow doesn't break. So this way, you don't have spooky action at a distance. They can make it do something cool at version 5, and you choose when you move by going in and saying, okay, now I'm going to version 5.
[57:56]Okay, but there's no danger in staying in the old version because nothing's vulnerable at this point. Is that right? Right.
[58:04]But if at some point in the future, when that's not true, when you run your workflow, instead of finishing with a green tick, it will finish with a yellow warning triangle, and it will say, using deprecated workflow, link to the details. And it might say, there's a security vulnerability upgrade to v5 or whatever.
[58:25]Okay. Got you.
[58:27]Yeah. So we do the first standard action, which is check out our code. The next standard action we want to use is to set up Node, because we're going to use NPM, so we need to have Node come into our virtual machine. And again, if you search for Node in the marketplace, you will find that there is one called set up Node at V4.
[58:51]Okay, there's a whole bunch of stuff if you ask for node from verified developers, but there you go. Setup-nodev4, got it.
[58:59]Yeah.
[59:00]Okay.
[59:00]And it would like an argument, which is, what version of node? So that's where the with keyword. So I said that users has a friend with that used to give it arguments. And so the description you're looking at in the marketplace says that you can say with and then node-version, which is why I'm saying with node version 22.x.
[59:23]How do you know it's 22.x to put in there?
[59:25]Because I went to the Node.js homepage and looked for the latest LTS. I was like, oh, LTS 22. Okay, I'll have 22. That was my choice.
[59:36]Okay.
[59:37]Now we're going to do an example of a run. And this is two terminal commands. So it's a multi-line string, which means in YAML speak, we start with a vertical pipe. So basically, that run is a two-liner, npmci, npx webpack.
[59:56]Okay, so that's a script.
[59:58]So that's two lines of terminal command.
[1:00:01]Got you. Okay.
[1:00:02]So at that point in time, the docs folder exists in the virtual machine. We've cloned the repository to the virtual machine, and it now exists. We now need to take the docs folder and basically zip it and the terminology used is that we make a pages artifact and that's just how github pages describes give me some stuff it calls it an artifact i don't know why i'm sure it's give me it's a cicd thing it's one of these terminologies like they like to talk about pipelines. An artifact is something you make. So we're making a web app. So that's our artifact. You're going to have to take the wording for me here. I didn't choose it.
[1:00:53]Yeah, but I don't know how I would find this because artifact gets 31 results.
[1:00:57]So I found it by asking it to give me, in the sidebar, you can ask it for example workflows. And I asked it for an example workflow of using GitHub pages. And it basically has a comment that says build your website and then actions upload pages artifact so i had to figure out how to do the node.js stuff and then i used their example code to make my artifact
[1:01:27]Okay. I don't know how I would know to do that. I guess there is an upload GitHub pages artifact.
[1:01:34]Yeah.
[1:01:34]And that's all you did?
[1:01:35]Yeah. Yeah, that is the action we have, right? Actions forward slash upload pages artifact at v3. And the width is what you want to make into the artifact. So we're saying our docs folder. So we've made our docs folder, and now we're saying take the docs folder and make it an artifact. And then we have a second job in our workflow. Which is, it says needs build. So we're naming it deploy, and we're saying it needs build. So that's how we're stopping these running in parallel, right? We're saying this one needs the previous one to happen. This one gets the permissions pages colon write, because we're letting it write our GitHub pages. Now, ID token, basically, that is a magic piece of sauce that the GitHub Pages doc says you have to give it. So the documentation said, you must do this. And I went, okay, I'll do that. The GitHub documentation also said I had to give it some environment stuff. I needed to give it an environment variable named GitHub-Pages. And I had to put this magic string in here.
[1:02:49]And for the URL. Yeah.
[1:02:52]It's sort of kind of...
[1:02:53]Why is it an env? Why is it environment, not ENV, like we said in the docs?
[1:02:58]I'm now trying to remember if it was one of those where you could do either. I am almost certain they let you have the short or the long version. And I copied and pasted from their example and didn't notice they used the long version.
[1:03:13]Okay. All right. That makes sense.
[1:03:15]Yeah. So we basically have to give it, the documentation told me to give it these pieces. And then our runs on is Ubuntu latest, and we have just one step, which we give the name Deploy to GitHub Pages. And again, the documentation told me I needed the action Deploy-Pages at V4.
[1:03:38]All right.
[1:03:39]So we have done in YAML what we did manually. We've described what and GitHub Pages works out the details. So with all of that done, we are going to basically, what do we need to do? This generates. Okay. So we've now have everything in place. Okay. So we are now going to clean up and test our automated deployment. So now that we're going to be building github pages inside the little temporary vm instead of having it exist in so the docs folder instead of having it exist in a repo we're going to create it you're going to do a really scary thing and delete the docs folder from your local copy of the repo yikes you could hang on this
[1:04:28]Just in i changed environment to env and on github.
[1:04:32]And it barfed all
[1:04:34]Over me and said no no no no that's an invalid workflow you broke everything don't know.
[1:04:38]What you're talking about in that case we need to update my shiny table to not be so short and it should be environment not env okay we'll
[1:04:46]Double check that but just in case keep an eye out for breaking changes yeah literally yes okay so now we're going to delete the local docs folder.
[1:04:55]Yeah delete it from the repo it doesn't need to exist in the repo now it's going to get created in the a little virtual machine and put to the internet.
[1:05:02]So this is just to prove it. Like you said, we could have it exist. If we're going to work on something locally a bunch before we push, it's going to create that docs folder.
[1:05:13]Right, but you're not going to commit that docs folder to the repository.
[1:05:16]Right, we're going to put it in gitignore.
[1:05:19]Exactly.
[1:05:20]But it will exist.
[1:05:22]Okay, yes. Yes, but it should be deleted from the repo. So the easiest way to delete it from the repo is to delete it locally and then do a git push or git commit git push now if you did that the action would run and you would end up with the identical web page so you would have no way to know that we've done anything so to prove to ourselves that we've actually done something different and the workflow really is building our website correctly we're also going to edit line 27 of src forward slash index.js and we're going to change the world modifier to automated webpack. So instead of it saying hello jQuery world, it will say hello automated webpack world. So when you're done with that, git commit, git push, and then open your GitHub web page again. Watch the action. Depending on how quick you are, you will or won't see it in progress. It'll finish. You'll see the URL. And there's your updated web page.
[1:06:26]It worked. That was very exciting seeing that change. I'm glad you had us delete it, not just git ignore it, because that's just mind-blowing to me that the docs folder stopped existing and yet it's still working. That's cool.
[1:06:41]Yeah, there we go. That little virtual machine. It's magic. Well, not magic, but indistinguishable from, right? Technology, et cetera.
[1:06:49]Yeah.
[1:06:50]So we have seen our first CICD pipeline for real. And we can now finally, after three years, publish our web apps to the real internet. And I wanted to do this to close that circle, but I had an ulterior motive, or not an ulterior, an additional motive. We as a community of PBS have been working at rebuilding xkpasswd to JavaScript. And that is how the web page is going to be published when it comes out of beta later this year. So right now it's at beta.xkpasswd. It's going to go to production and it will be doing so with a CICD pipeline using Webpack. So this is how it will be done.
[1:07:40]Very cool. Very cool. I just thought of something, Bert. Okay. You know what we should do? We should put a note at the end of PBS 138 to say, hey, PBS 176, you get to learn how to actually do it.
[1:07:53]That's a good point. No, you're dead right. Yes, I will. I will go back and do that.
[1:07:58]I can do it.
[1:07:59]Oh, okay. Yeah, great.
[1:08:00]I have a post-it note ready right here.
[1:08:02]Oh, good. Yeah. i've decided to become environmentally friendly i have replaced my post-it notes with these for people watching these are the world's tiniest uh dry wipe boards they are little colored squares about six inches by six inches that you ride on with the dry wipe marker and i just have i have a bunch of them i have a green one a pink one a yellow one and i use them as post-it notes and then i can rub them out later because i also have the world's tiniest little dog bone shaped eraser. Little dog bone.
[1:08:31]I wish you all could see this, but I actually have almost pulled the trigger on those a bunch of times, and I haven't quite done it. They have them where they have little magnets that can stick them to the refrigerator and everything.
[1:08:43]You can buy a magnetic tape, and so you can stick a strip of it along the bottom of your monitor, and then like air traffic control, you can have your little post-it notes moving across your monitor when you have a lot of tasks.
[1:08:53]Ew, I'm not sticking that to my monitor. Alright, let's finish this.
[1:08:57]Sorry, that's final thoughts, not how to buy dry wipe markers. Anyway. So we have now covered our little 10% on web apps, and we've closed that circle from three years ago. So we are now going to, for the rest of this series on GitHub Pages, we're changing to using GitHub Pages as a content management system, which is GitHub Pages' default behavior. So while there will be an action, and we can watch the action do its thing, we're not going to have to write the action. We're going to use GitHub's default action, which actually is an action that calls a static site generator named Jekyll. And so instead of us having to do all the hard work, we just get to say, use their default. But we're going to know what it's doing because that default is doing exactly what we've just done. But instead of it being our YAML file, it's a YAML file maintained by GitHub. But it's the same thing. and instead of NPM, it's Jekyll and instead of Webpack,
[1:10:04]It's Jekyll It does make me wonder what Hyde is, Jekyll's the static site generator and Hyde is what you see That's an interesting.
[1:10:14]Yeah, because one of them's evil and one of them isn't Yeah,
[1:10:16]I don't remember which one Dr.
[1:10:19]Jekyll and Mr. Hyde Dr. Jekyll has the higher title so he's the good guy That's how I remember it Dr.
[1:10:28]
Moving to CMS Mode
[1:10:29]Jekyll becomes Mr. Hyde hide anyway so we are going to be doing the automagic one where we don't have to do this in detail but i still think it's nice to understand what's happening under the hood and when you're looking at the output of the default action you're going to see it has three three jobs and two of them happen in parallel and you're going to watch it all happen and you're going to it's all going to make much more sense because it's all what we've just done now but again we're now switching into content management system mode, which is what we shall learn to do next time.
[1:11:02]All right. That sounds like fun. This was really interesting, Bart. I liked seeing the mechanism behind and learning the terminology makes so much sense.
[1:11:12]I was very pleased. I have had learn GitHub actions on my, oh God, I really need to list for years. And I kept on assuming it will be difficult. I had set aside, I think I'd set aside two weeks of my four weeks off, and then I ended up having health issues and stuff. And my four weeks off became effectively two. Thankfully, it only took me a day or two to do GitHub Actions.
[1:11:36]Oh, that's fantastic.
[1:11:38]Why have I been putting this off?
[1:11:41]According to Google's AI, the static generator on GitHub is called Jekyll because it was originally created by Tom Preston Werner, a developer at GitHub who named it after the fictional character Dr. Henry Jekyll from Robert Louis Stevenson's novel, The Strange Case of Dr. Jekyll and Mr. Hyde, likely due to the concept of transforming simple text files like Markdown into a fully rendered website mirroring the transformation of Jekyll into Hyde.
[1:12:05]I'd like to hope our content is less evil.
[1:12:12]
Conclusion and Sign Off
[1:12:13]All right, on that note, Bart, we should sign off.
[1:12:16]Indeed. Until next time, folks, happy computing.
[1:12:22]If you learn as much from Bart each week as I do, I'd like you to go over to lets-talk.ie and press one of the buttons over there to help support him. He does 98% of the work here. I'm just the stooge that listens to him and asks the dumb questions. If you go over to lets-talk.ie, you can support him on Patreon, you can donate via PayPal, or you can use one of his referrals.
[1:12:46]Music