Self-updating academic CV built with RenderCV.
Write one YAML file per section, keep publications in a .bib file, and let GitHub
Actions render a fresh PDF every time you push.
Live example: Marine Denolle's CV (PDF) — a 16-page academic CV maintained entirely through this system.
For researchers who value open science and technical transparency, a versioned CV in a public repo will most efficiently save you time to adapt your CV for various requests. It will gather your research impact stats pulling Google Scholar citation and github metrics automatically. Each section in the CV is a separate YAML file for modular writing. This template was modified from render-cv and entirely vibe coded after with Claude Opus 4.6 and Sonnet 4.6 using VsCode CoPilot agentic tools.
# Install pixi (cross-platform package manager)
curl -fsSL https://pixi.sh/install.sh | bash(Or use the Dockerfile for a pre-built environment.)
git clone https://github.com/your-username/marine-cv.git
cd marine-cv
pixi installRename the repository!
cp -r template/ my-cv-docs/
mv my-cv-docs/Your_Name_CV.yaml my-cv-docs/Jane_Doe_CV.yamlEach section is a separate YAML file — edit only what you need:
| File | What to put in it |
|---|---|
Your_Name_CV.yaml |
name, email, website, social links, section list |
employment.yaml |
positions, institutions, dates |
education.yaml |
degrees, advisor names |
your-publications.bib |
all publications (BibTeX) |
See marine-cv-docs/ for a complete working example across
all section types (grants, talks, datasets, mentoring, etc.).
Author formatting — edit DEFAULT_GROUP_MEMBERS in
src/rendercv/bibtex_parser.py so your mentees appear italic in author lists and your own name appears bold.
Citation counts — add your Scholar ID to social_networks in your CV YAML:
social_networks:
- network: Google Scholar
username: YOUR_SCHOLAR_ID # from scholar.google.com URL: ?user=YOUR_IDpixi run -- rendercv render my-cv-docs/Jane_Doe_CV.yamlYour PDF is at my-cv-docs/rendercv_output/Jane_Doe_CV.pdf. Push to GitHub and
the deploy-cv.yaml workflow commits a fresh render automatically.
marine-cv/
├── template/ ← START HERE — copy and edit these files
│ ├── Your_Name_CV.yaml ← main config (!include for each section)
│ ├── employment.yaml ← employment section stub
│ ├── education.yaml ← education section stub
│ └── your-publications.bib ← example BibTeX entries
│
├── marine-cv-docs/ ← live working example (Marine Denolle's CV)
│ ├── Marine_Denolle_CV.yaml ← main config
│ ├── *.yaml ← one file per CV section
│ ├── denolle-pub.bib ← 66 publications
│ └── rendercv_output/ ← rendered PDF/HTML (auto-committed by CI)
│
├── scripts/ ← automation (run by GitHub Actions)
│ ├── generate_publications.py ← BibTeX → publications_section.yaml
│ ├── fetch_citations.py ← Google Scholar h-index + citation counts
│ ├── fetch_github_stats.py ← GitHub/PyPI metrics
│ ├── fetch_youtube_stats.py ← YouTube channel stats
│ ├── update_cv_stats.py ← writes research_impact_summary.yaml
│ └── calculate_grant_totals.py ← Lead PI vs Co-PI totals
│
├── src/rendercv/ ← RenderCV library + custom BibTeX parser
│ └── bibtex_parser.py ← edit DEFAULT_GROUP_MEMBERS here
│
├── .github/workflows/ ← 5 targeted GitHub Actions (see below)
├── tests/ ← CI tests for publication generation
└── Dockerfile ← known-working build environment
Keep all publications in a .bib file and generate the formatted section:
python scripts/generate_publications.py > my-cv-docs/publications_section.yamlThen reference it in your CV YAML:
sections:
publications: !include publications_section.yamlWhat the generator does:
- APA-style author lists with bold PI and italic mentees
- Extracts DOIs →
https://doi.org/links - Pulls media coverage URLs from BibTeX
notefields (\url{https://...}) - Adds Google Scholar citation counts from cache
- Skips placeholder
doi: XXfor in-review papers
Media coverage in BibTeX:
@article{Your2024,
...
note = {\url{https://news.university.edu/press-release}},
}The first section of the CV auto-computes 6 metrics from local data files:
| Row | Source | Auto-updated? |
|---|---|---|
| Research Citations | citation_cache.json (OpenAlex + Google Scholar) |
Monthly (OpenAlex) / Manual (Google Scholar) |
| Publications | publications_section.yaml (T1/T2/T3 tier counts) |
On-push |
| Research Funding | grant_support.yaml (Lead PI vs Co-PI totals) |
On-push |
| Open-Source Software | github_stats_cache.json + PyPI |
Monthly |
| Mentoring | phd_advisees.yaml, postdocs.yaml, undergraduate_students.yaml |
Manual |
| Broader Impact | training_schools.yaml + YouTube stats |
Monthly |
Citation sources:
- OpenAlex (primary, auto-updated monthly) — fetched reliably from GitHub Actions
- Google Scholar (reference, manual) — fetched locally on your machine (Google blocks CI automation)
Regenerate at any time:
python scripts/update_cv_stats.pyNo library tests, no PyPI publishing, no executable builds.
| Workflow | Trigger | What it does |
|---|---|---|
deploy-cv.yaml |
push to marine-cv-docs/** or manual |
Renders CV, commits PDF/HTML |
validate-publications.yml |
push to .bib or scripts |
Regenerates + validates YAML, auto-commits |
update-citations.yml |
1st of month @ 2:00 UTC | Fetches OpenAlex citation metrics |
update-stats.yml |
1st of month @ 3:00 UTC | Fetches GitHub/PyPI/YouTube stats |
calculate-grants.yml |
push to grant_support.yaml |
Computes grant totals |
One optional secret: add YOUTUBE_API_KEY in Settings → Secrets → Actions
to enable YouTube stats. Everything else uses the built-in GITHUB_TOKEN.
The automated chain each month:
1st @ 2:00 UTC → citation_cache.json updated
1st @ 3:00 UTC → research_impact_summary.yaml updated
(triggers deploy-cv.yaml)
→ rendercv_output/ updated with fresh PDF
Since Google Scholar blocks automated requests from CI environments, manual updates are handled locally:
# Fetches your Google Scholar h-index and citation count
python scripts/fetch_google_scholar.py
# Updates CV with both OpenAlex and Google Scholar metrics
python scripts/update_cv_citations.pyManually add Google Scholar metrics to marine-cv-docs/citation_cache.json:
{
"metrics": {
"gs_h_index": 42,
"gs_total_citations": 8000,
"gs_last_updated": "2026-06-08T14:30:00"
}
}Then update the CV:
python scripts/update_cv_citations.pyBoth sources coexist in citation_cache.json:
{
"metrics": {
"openalex_total_citations": 5000, ← Auto-updated monthly (CI)
"openalex_h_index": 35, ← Auto-updated monthly (CI)
"i10_index": 28, ← Auto-updated monthly (CI)
"gs_h_index": 42, ← Manual update (this script)
"gs_total_citations": 8000, ← Manual update (this script)
"gs_last_updated": "ISO timestamp" ← When you last updated
}
}Your CV displays both: "5000 citations (OpenAlex) | 8000 citations, h-index: 42 (Google Scholar, last known)"
Theme and colors — edit the design: block in your CV YAML:
design:
theme: moderncv # classic | moderncv | sb2nov | engineeringresumes
colors:
name: rgb(128, 0, 0)
section_titles: rgb(69, 128, 179)Add or remove sections — each !include line in your CV YAML is one
section; delete or reorder to taste.
Publication display template — customize the layout per-entry:
design:
templates:
publication_entry:
main_column: "AUTHORS (DATE). **TITLE**. JOURNAL_WITH_DOI\nMEDIA_COVERAGE"BibTeX author bold/italic — edit DEFAULT_GROUP_MEMBERS in
src/rendercv/bibtex_parser.py. Your PI name is matched automatically.
rendercv: command not found
→ Use pixi run -- rendercv render ...
YAML indentation errors
→ Use 2 spaces, never tabs. Quote strings containing : or #.
Citations not appearing
→ For OpenAlex (auto): Run python scripts/fetch_citations.py --force-refresh
→ For Google Scholar (manual): Run python scripts/fetch_google_scholar.py or hand-edit citation_cache.json (see above)
Publications YAML invalid
→ Run python scripts/generate_publications.py locally and check stderr for
the full traceback.
url: https://doi.org/XX appears for in-review papers
→ This is filtered automatically. Re-run generate_publications.py if you see
placeholder URLs in the output.
Google Scholar fetcher fails with network errors
→ This is expected behind some firewalls/VPNs. Hand-edit citation_cache.json instead (see "Manually updating Google Scholar citations" above).
Built on RenderCV by Sina Atalay (MIT license). RenderCV handles YAML → Typst → PDF; this repository adds BibTeX integration, automated data pipelines, and a personal-CV-ready GitHub Actions setup.