name: Build Quarto Website
on:
push:
branches: [ main ]
workflow_dispatch:
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up R
uses: r-lib/actions/setup-r@v2
- name: Install system dependencies
run: |
sudo apt-get update
sudo apt-get install -y libfontconfig1-dev libfreetype6-dev libpng-dev libtiff5-dev libjpeg-dev
- name: Install quarto
uses: quarto-dev/quarto-actions/setup@v2
- name: Set up R dependencies with renv
uses: r-lib/actions/setup-renv@v2
- name: Render Quarto website
run: |
quarto render
- name: Deploy to Netlify
uses: nwtgck/actions-netlify@v2.0
with:
publish-dir: './_site'
production-branch: main
github-token: ${{ secrets.GITHUB_TOKEN }}
deploy-message: "Deploy from GitHub Actions"
env:
NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}
NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID }}
GitHub Action to Automatically Build Website
My Use Case & Motivation
This is for my personal documentation of how to create a GitHub Action to automatically build my website. If it benefits you that’ll be great!
In my case, I render my website using Quarto and have it hosted on Netlify. I want to automate the process of building the website whenever I push changes to my GitHub repository.
Netlify has a basic walk-through of website deployment upon GitHub push, which should solve the problem in most cases. I also documented my version of tutorial. However, it requires to fully construct the website on user’s local machine and push the built folder (usually the _site/
folder) to the repository. To do this, I need to always fully rebuild all website pages locally anytime I make changes, and the _site/
folder grows larger and larger over time.
Then I’m thinking of a solution of auto-building the website on GitHub upon push, and ignore the built folder in the repository. This tutorial documents my solution for my own record, and may also benefit you if you have similar needs.
Add Built Folder to .gitignore
The built folder is by default _site/
for Quarto. The first step is to add _site/
to your .gitignore
file so it’s no longer tracked by Git.
Create a GitHub Action Workflow
Then, create a GitHub Actions workflow file to build your site when you push to your repository. Create a file at .github/workflows/build.yml
with content like this:
Set Up Secrets in GitHub
NETLIFY_AUTH_TOKEN
and NETLIFY_SITE_ID
different:
NETLIFY_AUTH_TOKEN
is specific to your Netlify account, so usually you’ll only need one token.NETLIFY_SITE_ID
is specific to each site you deploy, so if you have multiple sites, you’ll need to set up the correspondingNETLIFY_SITE_ID
for each site.
Let’s set up NETLIFY_AUTH_TOKEN
and NETLIFY_SITE_ID
as secrets in the GitHub repository settings.
The NETLIFY_AUTH_TOKEN
can be generated from your Netlify account settings:
- Log in to Netlify.
- At the bottom left corner, click on your profile icon and select “User settings”.
- In the “Applications” tab, click on the “OAuth” seciton.
- Click on “New access token” to generate a new token.
- Copy the generated token and save it in a secure place, since you won’t be able to see it again.
The NETLIFY_SITE_ID
can be found in the settings of your Netlify site:
- Log in to Netlify.
- Select your site from the dashboard.
- Go to “Site Configuration”.
- Under “General” -> “Site details”, you will find the “Site ID”.
With these two secrets in hand, you can pass them to your GitHub repository:
- Go to your GitHub repository.
- Click on “Settings” in the repository menu.
- In the left sidebar, click on “Secrets and variables” -> “Actions”.
- Click on “New repository secret”.
- Add
NETLIFY_AUTH_TOKEN
and paste the token you generated. - Add
NETLIFY_SITE_ID
and paste the Site ID you found.
Change Netlify Settings for Site Deployment
Since we are deploying with GitHub, we don’t need Netlify to build the site anymore. Here is how to modify it:
- Log in to Netlify.
- Select your site from the dashboard.
- Go to “Site Configuration”.
- Under “Build & deploy” -> “Continuous Deployment” -> “Build settings”, click on “Configure”.
- Set “Build status” to “Stopped builds”.
Using renv
for R Package Dependencies
There are 2 ways to manage R package dependencies in your GitHub Actions workflow. One is to manually install all required packages, and the other is to use renv
to manage the dependencies. I chose to use renv
so I don’t need to manually update the package list in the workflow file.
You may have noticed that in the build.yml
file, I have these under the build jobs:
jobs:
build:
runs-on: ubuntu-latest
...
steps:
- name: Set up R dependencies with renv
uses: r-lib/actions/setup-renv@v2
This is to set up the R package dependencies using renv
.
Locaclly in your R console, run these to install and initialize renv
:
# Install renv if you don't have it
install.packages("renv")
# Initialize renv for your project
::init()
renv
# After you've used all the packages in your project
::snapshot() renv
When you run renv::init()
, it will create several files including:
renv.lock
: the package lockfile.Rprofile
: hidden, to activate renv when you open the projectrenv/
directory: contains project-specific package cache
The important file for GitHub Actions is renv.lock
, which contains information about all the packages your project needs. This file should be committed to your Git repository.
Two extra steps:
Firstly, in the future, any time you install new packages, you should locally run renv::snapshot()
again to let GitHub Actions intall the same packages automatically:
# Update the lockfile with new packages
::snapshot() renv
Another important step is when you switch to another computer or environment. You should run renv::restore()
to restore all packages from the lockfile:
# Restore all packages from the lockfile
::restore() renv
Conclusion
Now we are done. The site is still hosted on Netlify, but the building process is fully automated with GitHub Actions. Whenever you push changes to your GitHub repository, the site will be automatically built and deployed to Netlify. There is no need to push _site/
directory or manually rebuild the site locally.