My resume lives in a git repo. Every time I push, a GitHub Action compiles it to PDF and drops it on a stable URL. No local toolchain needed after the initial setup, no manually uploading PDFs anywhere.
Why LaTeX
Word docs drift. PDFs exported from Google Docs look fine until they don’t. LaTeX gives me exact control over layout and is just a text file — diffable, versionable, no binary blobs.
Because it’s plain text, it’s also machine readable. Parsers, scripts, LLMs — anything that can read a file can read your resume. That’s increasingly useful.
Git is version control by default. Every edit is tracked, every version is recoverable, and you can see exactly what changed between job applications.
I’m using the Awesome-CV template, which handles all the styling. I scaffolded the initial file with resumake.io, then checked the output into dcwfz9/resume and took it from there.
The compiler is xelatex — required by Awesome-CV for its font handling.
The workflow
The GitHub Actions workflow does four things on every push:
- Installs
texlive-xetexandtexlive-fonts-recommendedon Ubuntu - Runs
xelatex resume.tex - Uploads the PDF as a build artifact
- Deploys it to an orphan
buildbranch via peaceiris/actions-gh-pages
name: resume
on: [push]
jobs:
paper:
runs-on: ubuntu-latest
env:
DIR: .
FILE: resume
steps:
- uses: actions/checkout@v3
- name: Install TeXlive
run: sudo apt-get update && sudo apt-get install texlive-xetex texlive-fonts-recommended -y
- name: LaTeX compile
working-directory: ${{ env.DIR }}
run: xelatex ${{ env.FILE }}
- name: move
run: mkdir -p github_artifacts && mv ${{ env.DIR }}/${{ env.FILE }}.pdf ./github_artifacts/
- uses: actions/upload-artifact@v4
with:
name: ${{ env.FILE }}.pdf
path: ./github_artifacts
deploy:
needs: [paper]
runs-on: ubuntu-latest
permissions:
contents: write # not in my actual file, see below
steps:
- uses: actions/checkout@v4
- uses: actions/download-artifact@v4
with:
path: github_artifacts
- name: move
run: mkdir -p github_deploy && mv github_artifacts/*/* github_deploy
- uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./github_deploy
publish_branch: build
force_orphan: true
The workflow is adapted from Davide Gerosa’s 2021 template (a comment at the top of the real file says so; I trimmed that and the step names from the snippet). One difference from the real file is the permissions block. Pushing to the build branch needs write access for the workflow’s token. My repo’s Actions setting (Settings → Actions → General → Workflow permissions) is already set to read and write, which is why the real file works without the block. A repo set to read-only needs the block, or the setting changed, or the deploy step can’t push to build.
The orphan build branch keeps compiled output completely separate from source. The latest PDF is always at:
https://github.com/dcwfz9/resume/blob/build/resume.pdf
That one opens GitHub’s PDF viewer in the browser, which is the right link for a person to look at. For a direct download, or for something that fetches the file, use the raw URL:
https://github.com/dcwfz9/resume/raw/build/resume.pdf
Either is a permanent link I can put anywhere — job applications, portfolio, whatever. They’re always current.
Building locally
sudo apt-get install texlive-xetex texlive-fonts-recommended
xelatex resume.tex
The CI loop is fast enough that I mostly just push and check the Actions tab.
What I’d do differently
The workflow installs TeX packages fresh on every run, which takes ~2 minutes. Caching the apt layer or using a pre-built LaTeX Docker image would cut that significantly. Fine for now since I’m not updating the resume daily.
How this was built: this one’s mine, from before I used an AI agent. The repo dates to 2019 and the workflow to 2023, adapted from Davide Gerosa’s 2021 template. Since this March, Molty and Claude Code edit the resume’s text; the build hasn’t changed.