This post explains how to set up a GitHub repository so that it automatically compiles LaTeX documents to PDF, so that it can be viewed directly on GitHub, across different devices.
Although other tools, such as Overleaf, have similar features, and even provide real-time compilation, I still prefer GitHub for my everyday work, because I can use my favourite text editor Neovim, which increases my productivity, and because Git provides more powerful version control features.
Since setting up this workflow, it has also helped me in several, partly unexpected, ways:
In a collaborative project, when my collaborators make a change, I can see the updated PDF directly on my phone, without having to compile it myself.
When I post my papers on the arXiv, which is notorious for its unwillingness to move away from the technology of the 1990s (it hates Unicode!), it requires authors to use a specific old version of TeX Live to produce the
.bbl
bibliography file, then upload it. With this set-up, I can have GitHub do this for me without having to install this old version.
Of course, you still need to have a working LaTeX installation on your local machine to compile the document while you are writing it.
Contents
Setting permissions§
Before setting up the workflow, you need to set up the repository to allow GitHub Actions to create releases. To do this, follow these steps:
Go to your repository on GitHub, and go to the Settings tab.
In the Settings tab, click Actions in the sidebar, then click General.
Go to the Workflow permissions section, and check Read and write permissions.
Click the Save button in the Workflow permissions section. Note that this is not the Save button at the bottom of the page!
Now, we are ready to set up the workflow.
Adding the workflow file§
Create a .github
directory in the root of your repository
(note the leading dot),
and inside it, create a workflows
directory.
In the newly created .github/workflows
directory,
create a file build.yaml
with the following content:
name: Build PDF and release
on: push
jobs:
build_latex:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Compile LaTeX
uses: xu-cheng/latex-action@v3
with:
root_file: main.tex
- name: Get timestamp
run: echo "TIMESTAMP=$(date +'%Y-%m-%d %T')" >> $GITHUB_ENV
- name: Release
uses: softprops/action-gh-release@v2
with:
name: Draft ${{ env.TIMESTAMP }}
files: main.pdf
draft: true
If your main LaTeX file is not named main.tex
,
you should replace the main.tex
and main.pdf
above with your file names.
If your main file is in a subdirectory,
please see the documentation
of latex-action
for compiling it,
and replace main.pdf
with the path to your PDF file.
This workflow will then be triggered whenever you push to the repository, and it will do the following:
It will compile the LaTeX document in the repository.
It will create a draft release on GitHub named
Draft YYYY-MM-DD HH:MM:SS
, of course with the actual date and time. It will attach the compiled PDF to this release.If there is a previous draft release, it will overwrite it.
To view the PDF on GitHub, click Releases on your repository page, and the PDF will be in the Assets section of the latest draft release.
Customizations§
Here are some common customizations you might want to make:
To keep all versions of the PDFs, instead of overwriting the previous draft release, remove the
draft: true
line from the Release step.To change the date format in the release name, change the
date +'%Y-%m-%d %T'
in the Get timestamp step. This uses the Linuxdate
command to get the current date and time. See this tutorial, for example, for more options.To use a specific TeX Live version, add a
texlive_version
field to the Compile LaTeX step:- name: Compile LaTeX uses: xu-cheng/latex-action@v3 with: root_file: main.tex texlive_version: 2023
As of this writing, arXiv uses TeX Live 2023, which is what we have set it to here.
To also include the
.bbl
file required by the arXiv in the release, add it to the Release step:- name: Release uses: softprops/action-gh-release@v2 with: name: Draft ${{ env.TIMESTAMP }} files: | main.pdf main.bbl draft: true
For more customization options, see the documentation of the
latex-action
and
action-gh-release
actions.