Skip to content
Table of contents

CV: One repository, several publishing paths

This website combines bilingual CV pages, structured resume data, LaTeX PDFs and a Hugo blog. A local script builds and validates both the CV and blog, then publishes them together from docs/ on main.

Application and tools
  • Updated
  • 1
  • JavaScript · 36.98%
  • MIT
Documented components
2Explore modules
Source documents
10Read the instructions
Repository languagesJavaScript 36.98%11

Shares calculated from GitHub Linguist bytes.

JavaScript36.98%
36.98%584,457 bytes
HTML34.21%
34.21%540,538 bytes
Python10.17%
10.17%160,751 bytes
TeX8.19%
8.19%129,462 bytes
Language%Bytes
JavaScript36.98%584,457
HTML34.21%540,538
Python10.17%160,751
TeX8.19%129,462
CSS7.68%121,305
PowerShell0.99%15,654
5 more languages
Shell0.72%11,367
Batchfile0.54%8,498
Mermaid0.39%6,088
Go Template0.1%1,539
Jinja0.04%600

1. Overview

1.1. Why it exists

High-performance, accessible, bilingual static portfolio and CV with AEO schema, automated CI/CD, and zero runtime overhead.

1.2. Best fit

Professional software engineering presentation and technical documentation.

2. Use cases

Source of antoineboucher.info/CV: bilingual HTML CV, LaTeX PDFs, JSON résumé and a Hugo blog with project pages.

Use-case diagram for CV: Update CV content; Build the PDF résumés; Refresh project pages; Publish the site; Read the CV in EN or FR; Browse blog and projectsCVUpdate CV contentBuild the PDF résumésRefresh project pagesPublish the siteRead the CV in EN or FRBrowse blog and projectsSite ownerRecruiter or reader«system»GitHub Pages
People on the left, external systems on the right; each oval is a use case backed by the files cited below.
Update CV content
Site owner

The owner edits index-en.html and index-fr.html, data/resume.*.json and data/cv.yaml; scripts/build/generate_cv.py writes the LaTeX skills.tex files from the YAML.

Build the PDF résumés
Site owner

python build_cv.py build --all compiles cv-en/resume.tex and cv-fr/resume.tex with XeLaTeX inside a Docker image.

Refresh project pages
Site owner

scripts/build/repository_docs.py reads public repositories without running their code and writes hugo/data/repository_*.json, which the repository-note shortcode renders under hugo/content/projects/notes/<slug>/.

Publish the site
Site ownerGitHub Pages

scripts/deploy/publish_site.py runs build_docs.py (Hugo with HUGO_ENV=production, sitemap merge, deploy checks), check_public_repos.py and the note tests, then with --publish commits docs/ and pushes main.

Read the CV in EN or FR
Recruiter or readerGitHub Pages

GitHub Pages serves /CV/index-en.html and /CV/index-fr.html, the PDFs under /CV/cv-en/ and /CV/cv-fr/, and /CV/resume.json or /CV/resume.md for machine reading.

Browse blog and projects
Recruiter or readerGitHub Pages

The Hugo build is published at /CV/blog/ and /CV/blog/fr/, with a Markdown twin of each page and llms.txt, robots.txt and sitemap.xml copied to the site root.

2.1. Scenario: Ship a CV update

  1. Edit the job entry in index-en.html and index-fr.html and the matching data/resume.en.json and data/resume.fr.json.
  2. Run python build_cv.py build --all to rebuild cv-en/resume.pdf and cv-fr/resume.pdf.
  3. Run python scripts/deploy/publish_site.py to build the CV and blog into a staging folder, validate it and update docs/.
  4. Review docs/ locally, commit the source changes, then rerun the script with --publish to commit docs/ and push main.
  5. Wait for GitHub Pages (main, /docs) to process the push and check https://antoineboucher.info/CV/.

Files readREADME.mdscripts/deploy/publish_site.pyscripts/deploy/build_docs.pydocs/development/local-publishing.mdbuild_cv.pyscripts/build/generate_cv.pyscripts/build/repository_docs.py

3. Getting started

These commands come from the repository documentation. They were not run during this review.

README.md · Hugo blog (Paper)
cd hugo/themes/paper
npm ci
npm run build:css
cd ../..
hugo server -D
README.md · Building CVs
python build_cv.py build --language en
python build_cv.py build --all
python build_cv.py build --all --parallel
python build_cv.py build --language en --output ./output/cv.pdf
python build_cv.py build --language en --clean
python build_cv.py build --language en --verbose
python build_cv.py build --all --ci
README.md · LaTeX CVs
python build_cv.py build --language en
helm/cv-stack/README.md · Installation
helm install cv-stack ./helm/cv-stack
helm install cv-stack ./helm/cv-stack -f my-values.yaml
helm install cv-stack ./helm/cv-stack --namespace cv-stack --create-namespace
tools/medium-mirror/README.md · Setup
cd tools/medium-mirror
npm install
npx playwright install chromium
Tasks declared in manifests

4. Repository references

Excerpts from the repository’s guides, in their original language. Links open the inspected source revision.

Prerequisites and first run

4.1. Prerequisites

README.md

  • Python 3.8+ (for build script)
  • Docker (for LaTeX compilation)
  • Git
Read the full instructions ↗

4.2. Installation

README.md

  1. Clone the repository
  2. Install Python dependencies
  3. Build CV PDFs
  4. View locally
Read the full instructions ↗

4.3. Local Development

README.md

  1. Set up environment (see Local Development Guide)
  2. Make changes to HTML or LaTeX files
  3. Test locally using a local HTTP server
  4. Rebuild PDFs if LaTeX files changed
  5. Commit and push changes
Read the full instructions ↗

4.4. 🚀 Quick Start

docs/README.md

  1. Local Development: See Setup Guide
  2. Deploy to GitHub Pages: See GitHub Pages Deployment
  3. Compile CV: See CV Compilation
Read the full instructions ↗

4.5. Prerequisites (README.md)

docs/setup/README.md

Before starting, ensure you have:

  • Python 3.8+ - For the build script
  • Docker - For LaTeX compilation (recommended)
  • Git - For version control
  • Text Editor - For editing files (VS Code, Vim, etc.) Optional but recommended:
  • LaTeX Distribution - For local LaTeX compilation (alternative to Docker)
  • Node.js - For alternative HTTP server
Read the full instructions ↗
Configuration and usage

4.6. [Setup](./setup/README.md)

docs/README.md

Get started with the project - installation, requirements, and local development setup.

  • Local Development - Set up your local environment
  • Requirements - System requirements and dependencies
Read the full instructions ↗

4.7. Setup Guide

docs/setup/README.md

This section covers the initial setup and installation of the CV/resume website project.
Read the full instructions ↗

4.8. Configuration

helm/cv-stack/README.md

The following table lists the configurable parameters and their default values:

ParameterDescriptionDefault
namespace.nameNamespace namecv-stack
namespace.createCreate namespacetrue
cvSite.enabledEnable CV sitetrue
cvSite.replicasNumber of CV site replicas2
cvSite.image.repositoryCV site image repositorynginx
cvSite.image.tagCV site image tagalpine
linktreeSite.enabledEnable linktree sitetrue
linktreeSite.replicasNumber of linktree site replicas2
linktreeSite.image.repositoryLinktree site image repositorynginx
linktreeSite.image.tagLinktree site image tagalpine
traefik.enabledEnable Traefiktrue
traefik.replicasNumber of Traefik replicas1
traefik.image.repositoryTraefik image repositorytraefik
Read the full instructions ↗

4.9. Build Script Usage

docs/development/README.md

  • ✅ Always test builds locally before pushing
  • ✅ Use –verbose flag when debugging
  • ✅ Use –clean flag to remove auxiliary files
  • ✅ Use –all –parallel for faster builds
  • ✅ Check build statistics after compilation
  • ✅ Review LaTeX warnings and fix when possible
Read the full instructions ↗
Operations and troubleshooting

4.10. Deployment Issues

README.md

  • GitHub Pages not updating: Check GitHub Actions workflow status
  • Docker container issues: Check logs with docker-compose logs
  • Kubernetes issues: Check pod status with kubectl get pods See Troubleshooting Guide for more details.
Read the full instructions ↗

4.11. Recent Updates

README.md

  • ✅ CV index: Conferences section with Graphquon logos (2024 + 2025); moved out of certifications list
  • ✅ Added Graphquon 2024 and 2025 conference entries
  • ✅ Updated Snapchat Lens statistics (13.97M plays, 20.38M views; blog post refreshed May 2026)
  • ✅ Added DasherControl project
  • ✅ Updated hass-renpho with dates
  • ✅ Improved build script with parallel compilation support
  • ✅ Enhanced documentation structure

Built with ❤️ using LaTeX, Docker, and modern web technologies

Read the full instructions ↗

4.12. [Deployment](./deployment/README.md)

docs/README.md

Deploy the CV website to various platforms and environments.

  • GitHub Pages - Deploy to GitHub Pages
  • Docker - Docker-based deployment
  • Kubernetes - Kubernetes deployment
Read the full instructions ↗

4.13. Deployment Issues (README.md)

docs/README.md

Problem: GitHub Pages not updating

  • Solution: Check GitHub Actions workflow status
  • Solution: Verify Pages is enabled in repository settings
  • Solution: Check workflow logs for errors Problem: Docker container won’t start
  • Solution: Check container logs: docker-compose logs
  • Solution: Verify ports are not in use
  • Solution: Check Docker daemon is running Problem: Kubernetes pods not running
  • Solution: Check pod status: kubectl get pods -n cv-stack
  • Solution: View logs: kubectl logs -n cv-stack
  • Solution: Verify ingress is configured correctly
Read the full instructions ↗

4.14. Deployment Guide

docs/deployment/README.md

This section covers deploying the CV/resume website to various platforms and environments.
Read the full instructions ↗
Development and contributions

4.15. 🤝 Contributing

README.md

This is a personal CV/resume project. For suggestions or improvements, please open an issue or submit a pull request.
Read the full instructions ↗

4.16. [Development](./development/README.md)

docs/README.md

Development workflows, processes, and best practices.

  • CV Compilation - LaTeX CV compilation process
  • GitHub Actions - GitHub Actions workflows
  • Hugo blog (Paper theme) - Header, menus, i18n, baseURL, mobile menu, dark mode
Read the full instructions ↗

4.17. Option 1: Simple Local Server (Recommended for Quick Testing)

docs/setup/README.md

Use a simple HTTP server to view the website locally: Pros: Simple, no dependencies, fast startup Cons: No LaTeX compilation, basic features only
Read the full instructions ↗

4.18. 2. Test Build Script

docs/setup/README.md

Test the CV build script:
Read the full instructions ↗

4.19. Development Guide

docs/development/README.md

Development workflows, processes, and best practices for the CV/resume website project.
Read the full instructions ↗
Source documentation

10 documents read from 10 candidates.

5. Features and components 2

Content sources
data/resume.en.json and resume.fr.json hold the machine-readable resume. The index HTML pages remain canonical for their layout. data/aeo.yaml drives the generated About content, while Hugo owns the Markdown posts and project notes.
Assembly and verification
build_docs.py stages the root pages and assets, builds Hugo under the blog path, merges the root sitemap and runs deployment verification before copying the output to docs. Staging keeps a failed build from overwriting that published tree.

6. Architecture

Expand a component to follow its connections, or explore the full diagram.

System components Context
Mermaid Interactive diagram

System overview of the components and connections verified in the repository.

Static architecture view for CV
Static preview. The interactive diagram replaces it after Mermaid loads.
flowchart LR

subgraph group_resume["CV and Resume"]
  node_buildcv["CV Compiler<br/>[build_cv.py]"]
  node_latex_en["English LaTeX CV<br/>[resume.tex]"]
  node_latex_fr["French LaTeX CV<br/>[resume.tex]"]
  node_sections_en["English CV Sections"]
  node_sections_fr["French CV Sections"]
  node_pdf_en["English PDF Resume<br/>[resume.pdf]"]
  node_pdf_fr["French PDF Resume<br/>[resume.pdf]"]
  node_html_resume["HTML Resumes"]
  node_cv_data["CV Data<br/>[cv.yaml]"]
end

subgraph group_content["Portfolio Content"]
  node_hugo_content["Posts Projects Recipes"]
  node_hugo_layouts["Blog Templates"]
  node_papers["Papers and Publications"]
end

subgraph group_web["Website Experiences"]
  node_hugo_site["Hugo Blog"]
  node_linktree["Social Links Page"]
end

subgraph group_integration["External Integration"]
  node_agent_worker["Agent-ready Home Worker<br/>[worker.mjs]"]
  node_map_service["MapMyVisitors"]
end

node_visitor(("Site Visitor"))

node_visitor -->|"views resumes"| node_html_resume
node_visitor -->|"browses blog"| node_hugo_site
node_visitor -->|"opens links"| node_linktree
node_latex_en -->|"includes sections"| node_sections_en
node_latex_fr -->|"includes sections"| node_sections_fr
node_buildcv -->|"compiles source"| node_latex_en
node_buildcv -->|"compiles source"| node_latex_fr
node_buildcv -->|"produces PDF"| node_pdf_en
node_buildcv -->|"produces PDF"| node_pdf_fr
node_hugo_site -->|"renders content"| node_hugo_content
node_hugo_site -->|"uses templates"| node_hugo_layouts
node_visitor -.->|"reads publications"| node_papers
node_html_resume -->|"loads visitor map"| node_map_service


class node_buildcv,node_latex_en,node_latex_fr,node_sections_en,node_sections_fr,node_pdf_en,node_pdf_fr,node_html_resume,node_cv_data toneBlue
class node_hugo_content,node_hugo_layouts,node_papers toneAmber
class node_hugo_site,node_linktree toneMint
class node_agent_worker,node_map_service toneRose
class node_visitor toneIndigo

A bilingual CV and portfolio with HTML and PDF resumes, a Hugo blog, publications, social links and agent-readable routes. The build joins hand-edited content, generated resume data and deployment checks.

Components
17
Connections
13
Evidence-backed links
11/13
Text version of the diagram
  • Resume JSON and AEO data → Generated resume and About
  • Generated resume and About → Staged production build
  • HTML CV and LaTeX PDF → Staged production build
  • Hugo Markdown → Staged production build
  • Staged production build → Static docs website
Follow one path through the code

Follow a blog change from hugo/content into the Hugo build, then into the deployment staging directory. A CV data change follows another path, so updating a JSON record does not automatically rewrite every hand-edited HTML or LaTeX section.

7. Technical dossier

Built from the source at commit 2fdf469 (52 files). Each item comes from a pattern match in the code, so open the linked file before relying on it.

7.1. Layers and modules

Folders are sorted into layers by name, from the user interface down to data access. Because the sorting uses names only, the diagram says nothing about calls between layers.

Mermaid Layered view
flowchart TB
  subgraph L_presentation["Presentation"]
    direction TB
    presentation_0["hugo/layouts<br/>30 files"]
    presentation_1["(root)<br/>6 files"]
    presentation_2["css<br/>5 files"]
    presentation_3["linktree<br/>5 files"]
    presentation_more["+6"]
  end
  subgraph L_interface["Entry points and API"]
    direction TB
    interface_0["tools/medium-mirror<br/>1 file"]
  end
  subgraph L_application["Application services"]
    direction TB
    application_0["scripts/build<br/>5 files"]
    application_1["scripts/verify<br/>5 files"]
    application_2["scripts/html<br/>4 files"]
    application_3["cloudflare/workers<br/>1 file"]
    application_more["+2"]
  end
  subgraph L_core["Core source"]
    direction TB
    core_0["cv-en/latex<br/>9 files"]
    core_1["cv-fr/latex<br/>9 files"]
    core_2["cv-en<br/>2 files"]
    core_3["cv-fr<br/>2 files"]
    core_more["+3"]
  end
  subgraph L_tests["Tests"]
    direction TB
    tests_0["scripts<br/>4 files"]
  end
  subgraph L_hosting["Build, CI and hosting"]
    direction TB
    hosting_0[".github<br/>69 files"]
    hosting_1["helm<br/>11 files"]
    hosting_2["scripts<br/>11 files"]
    hosting_3["k8s<br/>8 files"]
    hosting_more["+2"]
  end
  L_presentation ~~~ L_interface
  L_interface ~~~ L_application
  L_application ~~~ L_core
  L_core ~~~ L_tests
  L_core ~~~ L_hosting
Modules and their main layer
ModuleLayerFilesTypesExtensions
hugo/layoutsPresentation300.html
cv-en/latexCore source90.tex
cv-fr/latexCore source90.tex
(root)Presentation71.html .py
cssPresentation50.css
linktreePresentation50.xml .css .html
scripts/buildApplication services50.py
scripts/verifyApplication services50.py
scripts/htmlApplication services40.py
cv-enCore source30.xml .tex .cls
cv-frCore source30.xml .tex .cls
hugoPresentation20.html
hugo/assetsPresentation20.css
papers/rapportPresentation20.html

7 smaller modules are not shown.

7.2. C4 model

From system context to code declarations. Each level reflects the available source evidence.

UML 1 · System context
1 · System context

The widest C4 view: who uses the project and which outside systems and data stores it relies on. Rendered with uml-mcp.

PlantUML source
@startuml
!include <C4/C4_Context>
LAYOUT_LEFT_RIGHT()
Person(P_cli, "CLI user")
System(SYS, "CV", "This website combines bilingual CV pages, structured resume data, LaT…")
Rel(P_cli, SYS, "Uses")
@enduml
UML 2 · Containers
2 · Containers

One level closer: the parts that run separately inside the project, their main language and how calls flow between them. Rendered with uml-mcp.

PlantUML source
@startuml
!include <C4/C4_Container>
LAYOUT_LEFT_RIGHT()
Person(P_cli, "CLI user")
System_Boundary(SYS, "CV") {
  Container(C0, "cv-site", "Docker")
  Container(C1, "linktree-site", "Docker")
  Container(C2, "traefik", "Docker")
}
Rel(P_cli, C0, "Uses")
@enduml
UML 3 · Components and layers
3 · Components and layers

Modules grouped by source-layer classification. Boundaries show organization, not runtime isolation or call relationships. Rendered with uml-mcp.

PlantUML source
@startuml
!include <C4/C4_Component>
LAYOUT_TOP_DOWN()
System_Boundary(SYS, "CV") {
Boundary(L0, "Presentation", "layer") {
Component(M0_0, "docs/blog", "HTML, .xml, .css", "1120 files")
Component(M0_1, "hugo/layouts", "HTML", "30 files")
Component(M0_2, "docs", "HTML, .xml", "7 files")
Component(M0_3, "(root)", "HTML", "6 files")
Component(M0_4, "docs/linktree", ".css, .xml, HTML", "6 files")
Component(M0_5, "css", ".css", "5 files")
Component(M0_6, "docs/css", ".css", "5 files")
Component(M0_7, "linktree", ".xml, .css, HTML", "5 files")
Component(M0_more, "+7 modules", "", "")
}
Boundary(L1, "Entry points and API", "layer") {
Component(M1_0, "docs/blog", "HTML, .xml", "12 files")
Component(M1_1, "tools/medium-mirror", ".mjs", "1 files")
}
Boundary(L2, "Application services", "layer") {
Component(M2_0, "scripts/build", "Python", "5 files")
Component(M2_1, "scripts/verify", "Python", "5 files")
Component(M2_2, "scripts/html", "Python", "4 files")
Component(M2_3, "cloudflare/workers", ".mjs", "1 files")
Component(M2_4, "scripts", "Python", "1 files")
Component(M2_5, "scripts/hugo", ".ps1", "1 files")
}
Boundary(L3, "Core source", "layer") {
Component(M3_0, "(root)", "Python", "1 files")
Component(M3_1, "docs/blog", "JavaScript", "1 files")
}
Boundary(L4, "Tests", "layer") {
Component(M4_0, "scripts", "Python", "4 files")
}
Boundary(L5, "Build, CI and hosting", "layer") {
Component(M5_0, ".github", ".md, .yml, JavaScript", "69 files")
Component(M5_1, "docs", "HTML, .xml, .md", "16 files")
Component(M5_2, "helm", ".yaml, .md, .tpl", "11 files")
Component(M5_3, "scripts", "Python, .ps1, .sh", "11 files")
Component(M5_4, "k8s", ".yaml", "8 files")
Component(M5_5, "(root)", ".cv, .nginx, .yml", "4 files")
}
}
@enduml
UML 4 · Code
4 · Code

Selected declarations, fields and methods grouped by source file. No inheritance or call edges are inferred. Rendered with uml-mcp.

PlantUML source
@startuml
skinparam backgroundColor transparent
skinparam shadowing false
skinparam roundCorner 10
skinparam defaultFontName Arial
skinparam defaultFontSize 13
skinparam ArrowColor #4e6070
skinparam ArrowFontColor #3d4f5f
skinparam titleFontSize 14
skinparam actorBorderColor #006a62
skinparam actorBackgroundColor #e9f3f4
skinparam usecaseBorderColor #006a62
skinparam usecaseBackgroundColor #e9f3f4
skinparam componentBorderColor #006a62
skinparam componentBackgroundColor #e9f3f4
skinparam interfaceBorderColor #006a62
skinparam interfaceBackgroundColor #ffffff
skinparam nodeBorderColor #4e6070
skinparam nodeBackgroundColor #f4f8fb
skinparam databaseBorderColor #006a62
skinparam databaseBackgroundColor #ffffff
skinparam cloudBorderColor #4e6070
skinparam cloudBackgroundColor #f0f5fa
skinparam artifactBorderColor #006a62
skinparam artifactBackgroundColor #ffffff
skinparam rectangleBorderColor #b0c2d3
skinparam activityBorderColor #006a62
skinparam activityBackgroundColor #e9f3f4
skinparam partitionBorderColor #b0c2d3
skinparam stereotypeCBackgroundColor #ffffff
top to bottom direction
hide empty members
package "CV" {
package "build_cv.py" as F0 {
class "LaTeXLogStats" as T0_0 {
  errors
  warnings
  overfull_boxes
  underfull_boxes
  pages
  has_fatal_error
}
}
object "build_cv.py" as FN0 {
  parse_latex_log()
  log()
  check_docker()
  get_cv_path()
  build_image()
  check_latex_quality()
}
object "scripts/html/patch_cv_html.py" as FN1 {
  failed()
  loadMap()
  initParticles()
  wrap_section_summaries()
  repl()
  patch_file()
}
object "tools/medium-mirror/import.mjs" as FN2 {
  pickSrcsetUrl()
  resolveUrl()
  extFromUrl()
  stripNoise()
  yamlEscape()
  extractArticleHtml()
}
object "scripts/verify/verify_deploy_build.py" as FN3 {
  q()
  validate_blog_nav()
  validate_agent_ready()
  validate_cv_pdfs()
  main()
}
object "scripts/verify/verify_meta_descriptions.py" as FN4 {
  _first_group()
  extract()
  check_file()
  main()
}
object "scripts/verify/verify_cv_pdf_text.py" as FN5 {
  pdftotext()
  check_pdf()
  main()
}
}
@enduml

7.3. Data flow

The calls from the GitDiagram graph, in the order you meet them from the entry points. GitDiagram generates the graph with AI; the file paths it cites were checked against the repository tree.

Mermaid Sequence diagram
sequenceDiagram
  autonumber
  participant P0 as CV Compiler
  participant P1 as English LaTeX CV
  participant P2 as French LaTeX CV
  participant P3 as English PDF Resume
  participant P4 as French PDF Resume
  participant P5 as Site Visitor
  participant P6 as HTML Resumes
  participant P7 as Hugo Blog
  participant P8 as Social Links Page
  participant P9 as Papers and Publications
  participant P10 as English CV Sections
  participant P11 as French CV Sections
  participant P12 as MapMyVisitors
  participant P13 as Posts Projects Recipes
  participant P14 as Blog Templates
  P0->>P1: compiles source
  P0->>P2: compiles source
  P0->>P3: produces PDF
  P0->>P4: produces PDF
  P5->>P6: views resumes
  P5->>P7: browses blog
  P5->>P8: opens links
  P5--)P9: reads publications
  P1->>P10: includes sections
  P2->>P11: includes sections
  P6->>P12: loads visitor map
  P7->>P13: renders content
  P7->>P14: uses templates
Steps as text
  1. CV Compiler to English LaTeX CV compiles source
  2. CV Compiler to French LaTeX CV compiles source
  3. CV Compiler to English PDF Resume produces PDF
  4. CV Compiler to French PDF Resume produces PDF
  5. Site Visitor to HTML Resumes views resumes
  6. Site Visitor to Hugo Blog browses blog
  7. Site Visitor to Social Links Page opens links
  8. Site Visitor to Papers and Publications reads publications
  9. English LaTeX CV to English CV Sections includes sections
  10. French LaTeX CV to French CV Sections includes sections
  11. HTML Resumes to MapMyVisitors loads visitor map
  12. Hugo Blog to Posts Projects Recipes renders content
  13. Hugo Blog to Blog Templates uses templates

7.4. Public interface

Outside code can use everything listed here. The project also declares 1 public types.

Command line 13

7.5. Private interface

These names are internal by the language’s conventions: a leading underscore, private, static or pub(crate).

underscore helper
9

Private modules

scripts/_repo.py

7.6. Entities and data model 1

EntityKindFirst fields
LaTeXLogStatsDataclasserrors, warnings, overfull_boxes, underfull_boxes, pages, has_fatal_error

7.7. Business logic

No classes were extracted, so these are the largest source files and their functions.

build_cv.py
parse_latex_log, log, check_docker, get_cv_path, build_image, check_latex_quality
scripts/html/patch_cv_html.py
failed, loadMap, initParticles, wrap_section_summaries, repl, patch_file
tools/medium-mirror/import.mjs
pickSrcsetUrl, resolveUrl, extFromUrl, stripNoise, yamlEscape, extractArticleHtml
scripts/verify/verify_deploy_build.py
q, validate_blog_nav, validate_agent_ready, validate_cv_pdfs, main
scripts/verify/verify_meta_descriptions.py
_first_group, extract, check_file, main
scripts/verify/verify_cv_pdf_text.py
pdftotext, check_pdf, main

7.8. Database and persistence

7.9. External integrations

HTTP clients

fetch

Hosts named in the code

7.10. Stack and dependencies

Python requirements.txt 3 runtime

Open the manifest

Node.js hugo/package.json 5 dev

Open the manifest

Node.js tools/medium-mirror/package.json 4 runtime

Open the manifest

External dependencies

12 declared packages (7 runtime, 5 development) in requirements.txt, hugo/package.json, tools/medium-mirror/package.json.

Package table 12
External dependencies
PackageVersionScopePurposeRegistry
typer>=0.9.0runtimeCommand linepypi.org
rich>=13.0.0runtimeCommand linepypi.org
tqdm>=4.66.0runtimeCommand linepypi.org
@tailwindcss/cli^4.1.18developmentUser interfacenpmjs.com
@tailwindcss/typography^0.5.16developmentUser interfacenpmjs.com
prettier^3.4.2developmentLinting and formattingnpmjs.com
prettier-plugin-go-template^0.0.15developmentLinting and formattingnpmjs.com
tailwindcss^4.1.18developmentUser interfacenpmjs.com
cheerio1.0.0-rc.12runtimeScraping and parsingnpmjs.com
playwright^1.49.0runtimeTestingnpmjs.com
turndown^7.2.0runtimeA library that converts HTML to Markdownnpmjs.com
turndown-plugin-gfm^1.0.2runtimeTurndown plugin to add GitHub Flavored Markdown extensions.npmjs.com

7.11. CI/CD pipeline

5 GitHub Actions workflows, 7 jobs. Each box is a job; double-bordered boxes publish or deploy, and arrows follow needs.

Mermaid Pipeline flow
flowchart LR
  subgraph wf0["Compile LaTeX CV"]
    direction LR
    wf0_compile["compile<br/>ubuntu-latest"]
  end
  subgraph wf1["Deploy to GitHub Pages"]
    direction LR
    wf1_deploy[["deploy<br/>ubuntu-latest"]]
  end
  subgraph wf2["Lighthouse CI"]
    direction LR
    wf2_lighthouse[["lighthouse<br/>ubuntu-latest"]]
  end
  subgraph wf3["Link check"]
    direction LR
    wf3_lychee["lychee<br/>ubuntu-latest"]
  end
  subgraph wf4["Quality checks"]
    direction LR
    wf4_spellcheck["spellcheck<br/>ubuntu-latest"]
    wf4_html_validate["html-validate<br/>ubuntu-latest"]
    wf4_en_fr_parity[["en-fr-parity<br/>ubuntu-latest"]]
  end
  t0(["push · manual run"])
  t1(["push · pull request · manual run"])
  t2(["push · pull request · manual run · schedule"])
  d0[("GitHub Pages")]
  t0 --> wf0_compile
  t0 --> wf1_deploy
  wf1_deploy -.-> d0
  t1 --> wf2_lighthouse
  t2 --> wf3_lychee
  t1 --> wf4_spellcheck
  t1 --> wf4_html_validate
  t1 --> wf4_en_fr_parity
Workflows, triggers, jobs and targets
WorkflowTriggersJobsPublishes to
Compile LaTeX CV
.github/workflows/compile-cv.yml
push, manual run
  • compile ubuntu-latest
    Checkout repository · Set up Python · Install Python dependencies · Set up Docker Buildx · Verify Docker is running · Verify required files exist
—
Deploy to GitHub Pages
.github/workflows/deploy.yml
push, manual run
  • deploy ubuntu-latest
    Checkout · Set up Python · Setup Pages · Install CI Python dependencies · Test sitemap merge script · Setup Hugo
GitHub Pages
Lighthouse CI
.github/workflows/lighthouse.yml
push, pull request, manual run
  • lighthouse ubuntu-latest
    actions/checkout · Set up Python · Setup Hugo · Setup Node · Build minimal _site for CV pages · Run Lighthouse CI
—
Link check
.github/workflows/link-check.yml
push, pull request, manual run, schedule
  • lychee ubuntu-latest
    Checkout repository · Check links · Link check report (advisory)
—
Quality checks
.github/workflows/quality.yml
push, pull request, manual run
  • spellcheck ubuntu-latest
    actions/checkout · Set up Python · Install spell tools · Locale spellcheck (EN codespell, FR aspell) · Spellcheck report (advisory)
  • html-validate ubuntu-latest
    actions/checkout · Setup Node · Validate static HTML
  • en-fr-parity ubuntu-latest
    actions/checkout · Set up Python · Install CI dependencies · Validate CV data schema · EN/FR HTML parity · Generated LaTeX matches data/cv.yaml
—

7.12. Deployment

Mermaid Deployment diagram
flowchart LR
  repo[("GitHub repository")]
  ci[["GitHub Actions<br/>5 workflows"]]
  image["Docker image<br/>FROM texlive/texlive:latest"]
  pub_GitHub_Pages[("GitHub Pages")]
  host_Vercel("Vercel<br/>vercel.json")
  host_Kubernetes_manifests("Kubernetes<br/>helm/cv-stack/")
  host_Static_site_generator("Static site<br/>hugo/hugo.toml")
  subgraph compose["Docker Compose"]
    svc_cv_site["cv-site"]
    svc_linktree_site["linktree-site"]
    svc_traefik["traefik"]
  end
  repo -->|"push or pull request"| ci
  ci -->|"docker build"| image
  ci -->|"publishes"| pub_GitHub_Pages
  ci -.->|"configured"| host_Vercel
  ci -.->|"configured"| host_Kubernetes_manifests
  ci -.->|"configured"| host_Static_site_generator
  image -->|"docker compose up"| compose
UML Deployment
Deployment

The outer node is where the code runs. Each base image points to what it builds, solid arrows lead to databases and dashed ones to outside services. Rendered with uml-mcp.

PlantUML source
@startuml
skinparam backgroundColor transparent
skinparam shadowing false
skinparam roundCorner 10
skinparam defaultFontName Arial
skinparam defaultFontSize 13
skinparam ArrowColor #4e6070
skinparam ArrowFontColor #3d4f5f
skinparam titleFontSize 14
skinparam actorBorderColor #006a62
skinparam actorBackgroundColor #e9f3f4
skinparam usecaseBorderColor #006a62
skinparam usecaseBackgroundColor #e9f3f4
skinparam componentBorderColor #006a62
skinparam componentBackgroundColor #e9f3f4
skinparam interfaceBorderColor #006a62
skinparam interfaceBackgroundColor #ffffff
skinparam nodeBorderColor #4e6070
skinparam nodeBackgroundColor #f4f8fb
skinparam databaseBorderColor #006a62
skinparam databaseBackgroundColor #ffffff
skinparam cloudBorderColor #4e6070
skinparam cloudBackgroundColor #f0f5fa
skinparam artifactBorderColor #006a62
skinparam artifactBackgroundColor #ffffff
skinparam rectangleBorderColor #b0c2d3
skinparam activityBorderColor #006a62
skinparam activityBackgroundColor #e9f3f4
skinparam partitionBorderColor #b0c2d3
skinparam stereotypeCBackgroundColor #ffffff
node "Docker Compose" as H {
  node "cv-site" as N0 <<container>>
  node "linktree-site" as N1 <<container>>
  node "traefik" as N2 <<container>>
}
artifact "FROM texlive/texlive:latest" as IMG0
IMG0 ..> N0 : builds
artifact "FROM nginx:alpine" as IMG1
IMG1 ..> N0 : builds
cloud "Vercel" as X0
X0 ..> N0
@enduml

Where it runs

Published to

Compose services

cv-site linktree-site traefik

Docker base images

texlive/texlive:latest nginx:alpine

7.13. Monitoring

What the code logs, measures and exposes to tell whether it is working.

Container health checks

7.14. Security

Controls

Supply chain

7.15. Testing

Test files
4
Source files
98
Test cases, about
13
Unit tests
4

No measured coverage report in the analyzed sources.

Where the tests are

scripts/tests 4

Nothing found for: Services.

8. Types and file structure

3 declared types, with 3 in the base-relationship overview.

Type diagram
classDiagram
direction TB
class tc629f4786497["LaTeXLogStats"] {
}
class tc217ab0df529["MergeRootSitemapTests"] {
  test_flattens_sitemapindex_and_adds_static_pages()
  test_urlset_passthrough()
}
class tb2eba65b8551["RenderResumeMdTests"] {
  test_render_en_contains_required_headings()
  test_all_locales_exit_zero()
}
class b539fd1ca9096["unittest.TestCase"] {
  <<unresolved_base>>
}
b539fd1ca9096 <|-- tc217ab0df529
class b18f4b7dc7f0d["unittest.TestCase"] {
  <<unresolved_base>>
}
b18f4b7dc7f0d <|-- tb2eba65b8551

Unresolved bases remain labelled; full signatures are not reconstructed.

9. Reference

43 / 43 eligible files read (2646 in the tree); 0 oversized, 0 failed reads and 0 syntax diagnostics.

What the scan covers

Known dependency/build folders, credential files and binaries are excluded. The scan covers READMEs, recognized manifests and parser-supported source files.

Linguist statistics cover the whole repository and may include other languages.

11. Files to read 4

12. Glossary

Repository

The versioned source files, configuration, and history of a project.

README

The repository’s entry document, usually covering its purpose and initial setup.

Dependency

A library, tool, or service that another component needs to build or run.

CLI

A text interface in which commands and arguments select operations. Exit codes let scripts detect success or failure.

Build

The steps that turn source files and dependencies into a runnable program or distributable artifact.

Mermaid

A text-based diagram language. Nodes and connections describe a model; the diagram itself does not execute the project.

13. References

  1. antoinebou12. (2026, November 5). CV. [Software repository] github.com.
  2. antoinebou12. (2026, November 5). CV: README. [Repository documentation] github.com.
  3. antoinebou12. (2026, November 5). scripts/deploy/build_docs.py. [Source file] github.com.
  4. antoinebou12. (2026, November 5). scripts/build/render_resume_md.py. [Source file] github.com.
  5. antoinebou12. (2026, November 5). scripts/build/generate_aeo_content.py. [Source file] github.com.
  6. antoinebou12. (2026, November 5). hugo/hugo.toml. [Source file] github.com.
  7. Boucher, A. (2026, October 24). Website refonte with Hugo (part 2). [Project article] antoineboucher.info.
  8. Boucher, A. (2026, October 23). CV: One repository, several publishing paths. [Project article] antoineboucher.info.

Sources without a publication date show the date they were last checked, November 5, 2026. File links retain the inspected revision where available.