Markdown-as-source-of-truth CV pipeline. Edit cv/cv.md, run one command, get HTML + PDF + DOCX.
Everything runs in Docker -- no local Pandoc or LaTeX install needed.
# Build all outputs
make build
# With contact info for PDF/DOCX
CV_EMAIL="you@example.com" CV_PHONE="+44..." make build
# Preview locally
make serve
# Open http://localhost:8000| Output | Path | Purpose |
|---|---|---|
| HTML | dist/index.html |
Public page with dark/light theme |
dist/cv.pdf |
Recruiter download (Inter font) | |
| DOCX | dist/cv.docx |
Editable export |
The HTML page includes download buttons and a theme toggle. Email and phone are excluded from the public HTML page.
cv/
cv.md # Source of truth
build.py # Build script
CNAME # Custom domain for GitHub Pages
templates/
cv.html.j2 # Tailwind HTML layout
cv.tex # LaTeX template (Inter, titlesec)
styles/
cv.css
Dockerfile # Pandoc + TeX Live + Inter font
Makefile # Docker-based build targets
.github/workflows/
build-cv.yml # CI: lint, build, deploy to GitHub Pages
.pre-commit-config.yaml # ruff, uv-lock, rust fmt/clippy
dist/ # Generated outputs (gitignored)
make build # Generate all outputs (HTML, PDF, DOCX)
make html # HTML only
make pdf # PDF only
make docx # DOCX only
make serve # Build and serve on port 8000
make clean # Remove dist/
make docker-build # Build the Docker image only
GitHub Actions pipeline on push to main:
- Lint -- pre-commit checks (ruff, trailing whitespace, yaml, etc.)
- Build -- Docker build, generate artifacts with secrets injected
- Deploy -- publish to GitHub Pages at lucaromagnoli.dev
Contact info (CV_EMAIL, CV_PHONE) is stored as GitHub secrets and injected at build time.
Full specification: SPEC.md.