LaTeX is a programming language built on the TeX typesetting system. It’s most commonly used in academia, and often used by Software Engineers for creating resumes. I ended up creating LatexResume to simplify the process of writing resumes.
Index
- What we’re looking for
- Exploring options
- Building in-house
- We can do better! Building LatexResume
- Extending
What we’re looking for
To create resumes in LaTeX the perfect solution should:
- Let us have full control over the content, structure and style of the document.
- Allow us to iterate on documents faster - make changes and see them immediately, similar to how Markdown to HTML tools work.
- Programmatically generate resumes for use in CI pipelines.
Exploring options
We have a few options when we want to start creating a resume:
- Overleaf is a fully featured LaTeX editor that we can use. It hosts a lot of pre-built templates, and has an editor similar to the one we’re looking for. However, I’m put off by the account requirement and lack of API.
- Resumake is another website that lets us create resumes using templates. It doesn’t allow the same amount of flexibility as Overleaf, but is open source.
- Build a solution in-house: Using a template available on GitHub, I can use pdfLaTeX to quickly build PDFs from
.tex
documents. Since every project is incomplete without classic over-engineering, I will build a website as well.
Building in-house
I picked up a template shared by Sourabh Bajaj on GitHub. I’ve seen it in use quite a bit and the README has all the instructions we need to build the resume PDF from the .tex
source.
Running pdfLaTeX
Documents written in LaTeX can be rendered as PDF using LaTeX engines similar to pdfLaTeX which we’ll use. The above repository contains a Dockerfile that can be used to run pdfLaTeX easily:
docker run --rm -i -v "$PWD":/data latex pdflatex resume.tex
This is super convenient to run LaTeX but it uses texlive-full
which needs at least 7 GiB disk space. If you’re running locally, you may face issues due to lack of disk space, slow internet or limited bandwidth. Running it on CI systems, you may again run into the same issues depending on the provider.
Integrating with CI
Using this repository as a starting point, we can wire up any CI tool to build the container image locally and build a PDF. On GitLab, the .gitlab.yml
file will look something like this:
resume-build:
image: docker:latest
stage: build
services:
- docker:dind
before_script:
- apk add --no-cache git
- git config --global user.name "John Doe"
- git config --global user.email "[email protected]"
- docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" $CI_REGISTRY
script:
- docker pull registry.gitlab.com/$GIT_USER_ID/resume:latest
- docker run --rm -i -v "$PWD":/data $image_uri pdflatex resume.tex
- git add .
- git commit -m "[ci skip] Update resume"
- git remote set-url origin https://gitlab-ci-token:${PERSONAL_ACCESS_TOKEN}@gitlab.com/jdoe/resume.git
- git push origin HEAD:main
In the above pipeline, we’re pulling a pre-built image we’ve pushed to the GitLab registry earlier, and using it to generate resume.pdf
. The resume then gets committed to the repository with [ci skip]
in the subject to avoid ending up in an endless loop.
For folks who use GitHub, I will share a similar workflow for Actions near the end.
We can do better! Building LatexResume
While the above solution works great, it can still be improved. I wrote a small API that could accept a file and return a rendered PDF as response, and a side-by-side editor using React that could let me write LaTeX and generate the PDF preview immediately.
You can use cURL on the terminal to convert a resume you have on disk to PDF instantaneously:
curl --fail --show-error -X 'POST' 'https://latexresume.com/api/v1/resume' \
-F '[email protected]' --output resume.pdf
And the React app itself is accessible by going to LatexResume.com.
I’m sure I’m missing some edge cases, but so far it’s worked for me without issues.
Extending
To finish things off, we can replace the Docker image build in our CI pipeline to utilize the LatexResume API instead. For GitHub Actions:
name: CI
on:
push:
branches: [ main ]
workflow_dispatch:
jobs:
update_resume:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Install dependencies
run: sudo apt -y update && sudo apt install -y curl git
- name: Build resume
run: |
curl --fail --show-error -X 'POST' 'https://latexresume.com/api/v1/resume' -F '[email protected]' --output resume.pdf
- name: Update resume
run: |
git config --global user.name 'John Doe'
git config --global user.email '[email protected]'
git add .
git commit -m "[ci skip] Update resume"
git push
That’s it! Let me know if you find the website useful.