Adding a basic GitHub Actions CI workflow
This lesson preview is part of the Bundling and Automation in Monorepos course and can be unlocked immediately with a \newline Pro subscription or a single-time purchase. Already have access to this course? Log in here.
Get unlimited access to Bundling and Automation in Monorepos, plus 90+ \newline books, guides and courses with the \newline Pro subscription.

[00:00 - 00:17] In this lesson, we're going to create a basic CI workflow for GitHub actions. I'm going to create a file in ./.github/workflows and call it just "ci.yaml". I'm going to paste the job that I've created ahead of time, and the structure is very simple.
[00:18 - 00:29] We have our name for the job. We have our triggers where we say we're going to trigger on the default pull request triggers which are open, closed and synchronized in GitHub.
[00:30 - 00:37] We have our list of jobs, and I'm going to just have one job called CI. And we're going to run on.
[00:38 - 00:45] Oh let me fix that. We can run on 24.04. We're going to run on Ubuntu 24.04.
[00:46 - 01:04] It's important to specify the version of Ubuntu you're running on instead of saying something like "ubuntu-latest", because sometimes that changes under you and suddenly your builds are broken. Always specify the exact version you're running on. Similarly, for actions, I always specify that I'm running on version five.
[01:05 - 01:08] Version 4.1. Version five. Like be explicit with the actions.
[01:09 - 01:18] We're going to be even more explicit in a later lesson, but this is fine for now as a starting point. You almost always start your actions by checking out your code.
[01:19 - 01:29] Then in our case, we want to set up pnpm. Afterwards, we want to set up Node by providing a node version file of .nvmrc.
[01:30 - 01:40] If you remember, our .nvmrc file just contains the major version number of Node that we want to be running on. Right now it's 22. And finally we need to run pnpm install.
[01:41 - 01:51] This is the setup that you would have in almost any action that needs to perform operations in a monorepo. And after that, you can run the actual commands that you want to run.
[01:52 - 02:06] In our case, we want to run the "test-types" the "lint", the "test", and the "build" commands for all workspace projects. We also want to run them even if one of the previous ones fails.
[02:07 - 02:28] So just for consistency on all of these, I've set "if: always()", which means even if a previous step fails, still execute the next step. The reason for that is that we want to collect all errors in a single run, rather than have people fix something here, only for them to have to wait for another CI run to see that there was another problem in linting.
[02:29 - 02:49] With that out of the way, I'm going to push this to GitHub and we can see it execute. I'm going to make a branch for it. Commit this as "Add initial CI config" and then push up to origin/add-ci.
[02:50 - 03:08] After I've done my push, I can go to GitHub and open a pull request for this. And we can see that the job immediately started. It's going to check out our source code.
[03:09 - 03:25] Install Node, do pnpm install, and then perform all the checks that we added. And it completed successfully. With that we can merge this pull request.
[03:26 - 03:48] And now that we have the code on master we can go into settings and we can add a rule for branch protection. I'm going to call this "Main branch rule".
[03:49 - 03:57] It is active with no bypasses. It targets the default branch which is the main branch.
[03:58 - 04:13] We make it so that it cannot be deleted. And we require a pull request before merging, and require status checks to pass by searching for the name of the job.
[04:14 - 04:29] So note that the status check name is the name of the job, which is just CI rather than CI... I'm going to call this "CI workflow". So the workflow name is not what you select.
[04:30 - 04:38] It's the job name that you select for checks. I've added the CI check and that's enough.
[04:39 - 05:05] Since this is a sensitive action, I'm going to be asked by GitHub to provide one time token. And now we have the branch protection rule in place. So when we create another pull request it would need to abide by this branch protection rule. If we go to the list of rules we can see that right now it applies to exactly one branch which is the main branch.
[05:06 - 05:09] And that's the basic setup for CI that we're going to start with.