I am learning GitHub Actions right now and have had a developer help me through the first two, which was a terrific learning experience. I plan to create a short videos series on this, but allow me to share what I believe to be accurate at a high-level (anyone can politely correct me if I am wrong):
GitHub Actions runs activities you define. They run based on triggers that can be based on things like:
- When someone closes an issue
- When code is pushed to a specified branch
- At a specific time of day, based on a CRON job
- When a human being runs the action manually
How do GitHub Actions run?
GitHub Actions is not much more than a file that instructs GitHub to run commands you define. It will run those things based on triggers (more on that in a minute). It will also open up a virtual environment (ubuntu, Mac, Windows, etc.).
You usually instruct GitHub Action to place a Docker image inside that virtual environment.
Docker images and containers
Docker is essentially a technology that allows you to run a trimmed-down operating system without going through the hassle of installing the whole OS each time. Docker containers can come with pre-installed software to make it easier for you to get started. You start with an image and then build a container from that image.
I created a video that shows you how to build Jekyll in a container on your computer without having to install Ruby or Jekyll on your computer. Here is the video that might be a good start for you:
Imagine you just purchased a computer with nothing on it. You install Linux and Ruby on it. Because you want a nice clean copy just in case you mess it up, you make a backup of your computer. Think of that backup as your image.
On that same computer, you install other apps, like Jekyll, Python, Git, Imagemagick, and other tools. You may also need to run certain scripts and commands. Think of that as your container.
So your container is a copy of an image and then you can mess around in it without ever ruining the original image.
In general, you can look at GitHub actions as a workflow that looks something like this:
Runs a file in the
./.github/workflows folder based on a trigger and runs a YAML file, like
The YAML file Instruct the workflow to open a virtual environment and open a Dockerfile
When the Dockerfile runs, it retrieves an image from a Docker repository. In my case, I use an official Ruby image that is available from the official Docker Repository (sort of an app store for images)
The Dockerfile can then run a script, which often points to
The script usually does all the “real” things you want to do with your GitHub action. Since you are basically in a shell command, you can do pretty much anything you need to. For example, it can build your Jekyll site and then copy it to another branch or another repo.
So it sort of goes like this
Entrypoint.sh [optionally] >
other script files
As of this writing, I have a GitHub Repo that contains my Jekyll 4.x code. GitHub Pages only support 3.9.x. However, GitHub Pages is just a web server, so it will always display standard HTML and CSS.
As I am sure you know, when you build a Jekyll site, it outputs industry-standard HTML and CSS. Those resultant files are no longer Jekyll, so GitHub Pages will happily display them.
I have a GitHub Action that opens my code repo, builds the Jekyll website, copies the files, and puts them into a second Website Repo where GitHub Pages is enabled, and my Agile in Action website automatically updates.
Also, I use ImageMagick to build featured images for every post. It creates a nice image that displays the name of the podcast and a picture of the guests. Since it can be very slow to use ImageMagick locally, my
entrypoint file not only builds and builds and copies the Jekyll site, it runs a Python script that uses ImageMagick to build the featured images for every post.
I have a file called
push.yml in my
.github/workflows folder. The workflow opens my Dockerfile, which instructs it to get a Docker image based on Ruby (required for Jekyll) and the Alpine Linux variant (because it is small and fast). The Dockerfile contains instructions to build a Docker container from an image and install Jekyll, Python, and ImageMagick.
At the end of my Dockerfile code, I have a line that says run
sh extension means “shell”.
In my case, my
entrypoint is a BASH shell script that runs the ImageMagick Python script, builds the Jekyll site, then copies the changed website files over to my GitHub website repo. Once complete, my website is up to date!
Pricing and consumption
Now that you know a GitHub Action is pretty much anything you can imagine doing in a command line, including installing and using other software products, GitHub cannot assume your use case.
For example, I doubt the GitHub team ever sat around in a room and assumed I would install Python and ImageMagick on my site to build featured images.
For that reason, GitHub says, “Do what you want, but with limitations on how long you do it”. Note that GitHub Actions are also called CI/CD (continuous improvement/continuous development).
As of this writing, the GitHub free tier allows you up to 2,000 CI/CD minutes a month.
When I go to the GitHub Actions page, I can see my workflow takes approximately 5 minutes. Here are my approximate numbers:
Automatic daily build: 5 minutes/day * 30 days = 150 minutes
Code pushes (usually new podcast posts): 4 updates/week * 5 minutes * 4 weeks = 80 minutes
Total usage: 230 minutes/month out of a possible 2,000 minutes/month
Late last year, my GitHub Action was very inefficient. ImageMagick would rebuild every featured image for every post. Also, the Docker container took a long time to install the components I required.
Every GitHub Action run took 20 minutes, which is 920 minutes/month. Worrying about my carbon footprint, I made two significant changes:
- Build with a Docker image that is small, compact, and fast (Ruby Alpine)
- Adjust my ImageMagick scripts to only work with new posts, not older ones
With those small changes, I saved 8,280 worth of computing minutes per year . Every little bit counts!
About pre-built GitHub Actions
I find people use pre-built GitHub Actions and do not know how they work. For example, you might find a great GitHub Action that builds your Jekyll site. But does the action do anything else? Was it designed a long time ago, and are there better methods? I highly recommend you minimally learn Docker and shells like BASH and ZSH so you can read what the workflow does before putting it into production.
I know the pre-built GitHub actions you are using are from reputable sources, so please do not take my comments to say that you are doing anything wrong. It is more of a word of warning.
Looking for ideas
I hope that helps and if there is anything you want me to put into a training video, please let me know because I am sketching them at the moment.
If I am wrong about any of this, please be nice. I am not an expert