Automating LaTeX to PDF Conversion with GitHub Actions
- Automating LaTeX to PDF Conversion with GitHub Actions
- Test Blog
Changelog:
Ive tweaked the workflow to include a timestamp in the PDF file, Also changed the action trigger to pushes made only to the resume latex file.
Hello there! Today, I'm excited to share a neat little trick I've been using to automate the conversion of my LaTeX manuscripts into PDF and PNG formats using GitHub Actions. This has been a game-changer for me, especially when working on my resume and academic papers. Let's dive in!
The Problem
Ever since a friend introduced me to LaTeX for creating resumes, I've become an avid user.
Frequently, I find myself needing to convert these documents into PDF and PNG formats.
This need became particularly evident when I began updating my resume.
Initially, I used Overleaf for this task, which was straightforward. However, as I transitioned to using Visual Studio Code and compiling locally, the process became more complex.
I remembered that Overleaf offered an automatic push feature for manuscripts to a GitHub repository.
Unfortunately, this was a paid feature and I no longer used the platform.
Recognizing the value of this feature, I was determined to find a way to replicate it. In the interim, I resorted to manually updating my GitHub repository with the latest versions of my manuscripts in both PDF and PNG formats. This manual process was not only time-consuming but also prone to errors. I yearned for a solution that could automate this process, ensuring that my GitHub repository was always up-to-date with the latest versions of my manuscripts.
GitHub Actions to the Rescue
GitHub Actions is a powerful tool that allows you to automate, customize, and execute your software development workflows right in your repository. I realized that I could leverage GitHub Actions to automate the conversion of my LaTeX manuscripts into PDF and PNG formats and push the updated files to my GitHub repository on every push event. This would ensure that my repository was always up-to-date with the latest versions of my manuscripts, without any manual intervention from me.
Using GitHub Actions
GitHub Actions allows you to create custom workflows that can be triggered by various events, such as push, pull request, issue, and more.
Each workflow is defined in a YAML file within the .github/workflows
directory of your repository.
The workflow file contains a series of jobs, each of which can contain multiple steps.
Each step can run commands, execute a script, or use an action, which is a reusable unit of code that can be used in a workflow.
In my case, I created a workflow that runs on every push event and consists of several steps to build my LaTeX documents, convert them to PDF and PNG formats, and push the updated files to my repository.
The Workflow
Here's the GitHub Actions workflow I've created, which I've named LaTex2PDF:
name: LaTex2PDF
on:
push:
jobs:
build:
runs-on: ubuntu-latest
env:
MANUSCRIPT_PATH: latexResume/main
LATEX: pdflatex
steps:
- uses: actions/checkout@v4.1.1
This workflow is triggered every time I push to my repository. It runs on the latest version of Ubuntu and uses the pdflatex engine to build my LaTeX documents.
Building the Manuscript
The first few steps of the workflow involve checking out the latest code from my repository and installing the necessary TeX Live packages to build LaTeX documents:
- uses: actions/checkout@v4.1.1
- name: Install texlive
run: |
sudo apt-get install texlive-publishers \
texlive-latex-recommended \
texlive-latex-extra \
texlive-fonts-recommended \
texlive-fonts-extra
- name: Build resume
run: |
cd ${MANUSCRIPT_PATH%/*}
${LATEX} ${MANUSCRIPT_PATH##*/}.tex
Once the environment is set up, the workflow navigates to the directory containing my LaTeX file and builds the PDF.
Pushing the PDF
After the PDF is built, the workflow adds it to my repository and pushes the changes back to GitHub:
- name: Push resume
run: |
cd ${MANUSCRIPT_PATH%/*}
git add -f ${MANUSCRIPT_PATH##*/}.pdf
git -c user.name='resume-maker' -c user.email='resume-maker' commit -m "update pdf"
git push -q -f https://${{ github.actor }}:${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }}
This ensures that the latest version of my resume is always available in PDF format in my repository.
Converting PDF to PNG
The next few steps involve installing Ghostscript, modifying the security policy of ImageMagick, and converting the PDF into a PNG image:
- name: Install ghostscript
run: sudo apt-get update --fix-missing && sudo apt install ghostscript
...
- name: Convert PDF to PNG
run: |
cd ${MANUSCRIPT_PATH%/*}
convert -density 900 -background white -alpha off ${MANUSCRIPT_PATH##*/}.pdf -resize 25% -quality 90 -colorspace RGB ${MANUSCRIPT_PATH##*/}.png
And voila! The latest versions of my resume in both PDF and PNG formats are always available in my repository, without any manual intervention from me.
Plus, I can link the PNG in the GitHub readme like so
![](latexResume/main.png)
and have the PNG displayed on GitHub.
Full .yml code
name: LaTex2PDF
# description: build LaTex manuscripts and push the latest PDF and PNG back to GitHub
on:
push:
paths:
- 'latexResume/resume.tex'
jobs:
build:
runs-on: ubuntu-latest
env:
MANUSCRIPT_PATH: latexResume/main
LATEX: pdflatex
steps:
- uses: actions/checkout@v1
- name: Install texlive
run: |
sudo apt-get install texlive-publishers \
texlive-latex-recommended \
texlive-latex-extra \
texlive-fonts-recommended \
texlive-fonts-extra
- name: Build resume
run: |
cd ${MANUSCRIPT_PATH%/*}
${LATEX} ${MANUSCRIPT*PATH##*/}.tex
- name: Push resume
run: |
git checkout --orphan ${GITHUB_REF##*/}
cd ${MANUSCRIPT_PATH%/*}
git add -f ${MANUSCRIPT_PATH##*/}.pdf
git -c user.name='resume-maker' -c user.email='resume-maker' commit -m "update pdf"
git push -q -f https://${{ github.actor }}:${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }}
- name: Install ghostscript
run: sudo apt-get update --fix-missing && sudo apt install ghostscript
- name: Change ImageMagick security policy
run: |
DQT='"'
SRC="rights=${DQT}none${DQT} pattern=${DQT}PDF${DQT}"
RPL="rights=${DQT}read\|write${DQT} pattern=${DQT}PDF${DQT}"
HGT="name=${DQT}height${DQT} value=${DQT}10KP${DQT}"
HGTR="name=${DQT}height${DQT} value=${DQT}128Kp${DQT}"
WDT="name=${DQT}width${DQT} value=${DQT}10KP${DQT}"
WDTR="name=${DQT}width${DQT} value=${DQT}128Kp${DQT}"
MAP="name=${DQT}map${DQT} value=${DQT}512MiB${DQT}"
MAPR="name=${DQT}map${DQT} value=${DQT}4GiB${DQT}"
MEM="name=${DQT}memory${DQT} value=${DQT}256MiB${DQT}"
MEMR="name=${DQT}memory${DQT} value=${DQT}2GiB${DQT}"
sudo sed -i "s/$SRC/$RPL/" /etc/ImageMagick-6/policy.xml
sudo sed -i "s/$HGT/$HGTR/" /etc/ImageMagick-6/policy.xml
sudo sed -i "s/$WDT/$WDTR/" /etc/ImageMagick-6/policy.xml
sudo sed -i "s/$MAP/$MAPR/" /etc/ImageMagick-6/policy.xml
sudo sed -i "s/$MEM/$MEMR/" /etc/ImageMagick-6/policy.xml
- name: Convert PDF to PNG
run: |
cd ${MANUSCRIPT_PATH%/*}
convert -density 900 -background white -alpha off ${MANUSCRIPT_PATH##*/}.pdf -resize 25% -quality 90 -colorspace RGB ${MANUSCRIPT_PATH##*/}.png
- name: Commit PNG
id: commit
run: |
cd ${MANUSCRIPT_PATH%/*}
git config --local user.email "action[bot]@github.com"
git config --local user.name "github-actions[bot]"
git add ${MANUSCRIPT_PATH##*/}.png
git commit -m "[bot] updated ${MANUSCRIPT_PATH##*/}.png"
- name: Push changes
uses: ad-m/github-push-action@master
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
name: LaTex2PDF
# description: build LaTex manuscripts and push the latest PDF and PNG back to GitHub
on:
push:
branches:
- timestamped-version
paths:
- 'latexResume/resume.tex'
jobs:
build:
runs-on: ubuntu-latest
env:
MANUSCRIPT_PATH: latexResume/resume
LATEX: pdflatex
steps:
- uses: actions/checkout@v4.1.1
- name: Install texlive
run: |
sudo apt-get install texlive-publishers \
texlive-latex-recommended \
texlive-latex-extra \
texlive-fonts-recommended \
texlive-fonts-extra
- name: Build resume
run: |
cd ${MANUSCRIPT_PATH%/*}
TIMESTAMP=$(date +%Y-%m-%d--%H-%M-%S)
${LATEX} ${MANUSCRIPT_PATH##*/}.tex
cp ${MANUSCRIPT_PATH##*/}.pdf ${MANUSCRIPT_PATH##*/}_latest.pdf
mv ${MANUSCRIPT_PATH##*/}.pdf ${MANUSCRIPT_PATH##*/}_$TIMESTAMP.pdf
echo "TIMESTAMP=$TIMESTAMP" >> $GITHUB_ENV
- name: Push resume
run: |
cd ${MANUSCRIPT_PATH%/*}
git add -f ${MANUSCRIPT_PATH##*/}_latest.pdf
git add -f ${MANUSCRIPT_PATH##*/}_$TIMESTAMP.pdf
git -c user.name='resume-maker' -c user.email='resume-maker' commit -m "update pdf"
git push -q -f https://${{ github.actor }}:${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }}
- name: Install ghostscript
run: sudo apt-get update --fix-missing && sudo apt install ghostscript
- name: Change ImageMagick security policy
run: |
DQT='"'
SRC="rights=${DQT}none${DQT} pattern=${DQT}PDF${DQT}"
RPL="rights=${DQT}read\|write${DQT} pattern=${DQT}PDF${DQT}"
HGT="name=${DQT}height${DQT} value=${DQT}10KP${DQT}"
HGTR="name=${DQT}height${DQT} value=${DQT}128Kp${DQT}"
WDT="name=${DQT}width${DQT} value=${DQT}10KP${DQT}"
WDTR="name=${DQT}width${DQT} value=${DQT}128Kp${DQT}"
MAP="name=${DQT}map${DQT} value=${DQT}512MiB${DQT}"
MAPR="name=${DQT}map${DQT} value=${DQT}4GiB${DQT}"
MEM="name=${DQT}memory${DQT} value=${DQT}256MiB${DQT}"
MEMR="name=${DQT}memory${DQT} value=${DQT}2GiB${DQT}"
sudo sed -i "s/$SRC/$RPL/" /etc/ImageMagick-6/policy.xml
sudo sed -i "s/$HGT/$HGTR/" /etc/ImageMagick-6/policy.xml
sudo sed -i "s/$WDT/$WDTR/" /etc/ImageMagick-6/policy.xml
sudo sed -i "s/$MAP/$MAPR/" /etc/ImageMagick-6/policy.xml
sudo sed -i "s/$MEM/$MEMR/" /etc/ImageMagick-6/policy.xml
- name: Convert PDF to PNG
run: |
cd ${MANUSCRIPT_PATH%/*}
convert -density 900 -background white -alpha off ${MANUSCRIPT_PATH##*/}_$TIMESTAMP.pdf -resize 25% -quality 90 -colorspace RGB ${MANUSCRIPT_PATH##*/}.png
- name: Commit PNG
id: commit
run: |
cd ${MANUSCRIPT_PATH%/*}
git add -f ${MANUSCRIPT_PATH##*/}.png
git -c user.name='resume-maker' -c user.email='resume-maker' commit -m "update png"
git push -q -f https://${{ github.actor }}:${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }}
Wrapping Up
Lastly, the finishing touch, in order to add a download link to my resume on this very site, I utilized the GitHub raw link. By using the raw link of the PDF file in my GitHub repository, I was able to generate a download link for the resume on my website. Allowing visitors to easily access and download the latest version of my resume.
I hope you found this post helpful! Automating this process has saved me a lot of time and effort, and I hope it can do the same for you. Happy coding!
- Automating LaTeX to PDF Conversion with GitHub Actions
- Test Blog