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.
- Languages
- 11Code breakdown
- Documented components
- 2Explore modules
- Source documents
- 10Read the instructions
Repository languagesJavaScript 36.98%11
Shares calculated from GitHub Linguist bytes.
| Language | % | Bytes |
|---|---|---|
| JavaScript | 584,457 | |
| HTML | 540,538 | |
| Python | 160,751 | |
| TeX | 129,462 | |
| CSS | 121,305 | |
| PowerShell | 15,654 |
5 more languages
| Shell | 0.72% | 11,367 |
| Batchfile | 0.54% | 8,498 |
| Mermaid | 0.39% | 6,088 |
| Go Template | 0.1% | 1,539 |
| Jinja | 0.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.
- 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
- Edit the job entry in index-en.html and index-fr.html and the matching data/resume.en.json and data/resume.fr.json.
- Run python build_cv.py build --all to rebuild cv-en/resume.pdf and cv-fr/resume.pdf.
- Run python scripts/deploy/publish_site.py to build the CV and blog into a staging folder, validate it and update docs/.
- Review docs/ locally, commit the source changes, then rerun the script with --publish to commit docs/ and push main.
- 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.
cd hugo/themes/paper
npm ci
npm run build:css
cd ../..
hugo server -Dpython 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 --cipython build_cv.py build --language enhelm 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-namespacecd tools/medium-mirror
npm install
npx playwright install chromiumTasks 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
4.2. Installation
README.md
- Clone the repository
- Install Python dependencies
- Build CV PDFs
- View locally
4.3. Local Development
README.md
- Set up environment (see Local Development Guide)
- Make changes to HTML or LaTeX files
- Test locally using a local HTTP server
- Rebuild PDFs if LaTeX files changed
- Commit and push changes
4.4. 🚀 Quick Start
docs/README.md
- Local Development: See Setup Guide
- Deploy to GitHub Pages: See GitHub Pages Deployment
- Compile CV: See CV Compilation
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
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
4.7. Setup Guide
docs/setup/README.md
4.8. Configuration
helm/cv-stack/README.md
The following table lists the configurable parameters and their default values:
| Parameter | Description | Default |
|---|---|---|
| namespace.name | Namespace name | cv-stack |
| namespace.create | Create namespace | true |
| cvSite.enabled | Enable CV site | true |
| cvSite.replicas | Number of CV site replicas | 2 |
| cvSite.image.repository | CV site image repository | nginx |
| cvSite.image.tag | CV site image tag | alpine |
| linktreeSite.enabled | Enable linktree site | true |
| linktreeSite.replicas | Number of linktree site replicas | 2 |
| linktreeSite.image.repository | Linktree site image repository | nginx |
| linktreeSite.image.tag | Linktree site image tag | alpine |
| traefik.enabled | Enable Traefik | true |
| traefik.replicas | Number of Traefik replicas | 1 |
| traefik.image.repository | Traefik image repository | traefik |
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
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.
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
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
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
4.14. Deployment Guide
docs/deployment/README.md
Development and contributions
4.15. 🤝 Contributing
README.md
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
4.17. Option 1: Simple Local Server (Recommended for Quick Testing)
docs/setup/README.md
4.18. 2. Test Build Script
docs/setup/README.md
4.19. Development Guide
docs/development/README.md
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.
Resume JSON and AEO data
Generated resume and About
HTML CV and LaTeX PDF
Hugo Markdown
Staged production build
Static docs website
Mermaid Interactive diagram
System overview of the components and connections verified in the repository.

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 toneIndigoA 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
| Module | Layer | Files | Types | Extensions |
|---|---|---|---|---|
hugo/layouts | Presentation | 30 | 0 | .html |
cv-en/latex | Core source | 9 | 0 | .tex |
cv-fr/latex | Core source | 9 | 0 | .tex |
(root) | Presentation | 7 | 1 | .html .py |
css | Presentation | 5 | 0 | .css |
linktree | Presentation | 5 | 0 | .xml .css .html |
scripts/build | Application services | 5 | 0 | .py |
scripts/verify | Application services | 5 | 0 | .py |
scripts/html | Application services | 4 | 0 | .py |
cv-en | Core source | 3 | 0 | .xml .tex .cls |
cv-fr | Core source | 3 | 0 | .xml .tex .cls |
hugo | Presentation | 2 | 0 | .html |
hugo/assets | Presentation | 2 | 0 | .css |
papers/rapport | Presentation | 2 | 0 | .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
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
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
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
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
- CV Compiler to English LaTeX CV compiles source
- CV Compiler to French LaTeX CV compiles source
- CV Compiler to English PDF Resume produces PDF
- CV Compiler to French PDF Resume produces PDF
- Site Visitor to HTML Resumes views resumes
- Site Visitor to Hugo Blog browses blog
- Site Visitor to Social Links Page opens links
- Site Visitor to Papers and Publications reads publications
- English LaTeX CV to English CV Sections includes sections
- French LaTeX CV to French CV Sections includes sections
- HTML Resumes to MapMyVisitors loads visitor map
- Hugo Blog to Posts Projects Recipes renders content
- 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
_existsscripts/ci/spellcheck.py:45_hugo_markdownscripts/ci/spellcheck.py:49_validate_aspell_pwsscripts/ci/spellcheck.py:99
Private modules
7.6. Entities and data model 1
| Entity | Kind | First fields |
|---|---|---|
LaTeXLogStats | Dataclass | errors, 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.pyparse_latex_log, log, check_docker, get_cv_path, build_image, check_latex_qualityscripts/html/patch_cv_html.pyfailed, loadMap, initParticles, wrap_section_summaries, repl, patch_filetools/medium-mirror/import.mjspickSrcsetUrl, resolveUrl, extFromUrl, stripNoise, yamlEscape, extractArticleHtmlscripts/verify/verify_deploy_build.pyq, validate_blog_nav, validate_agent_ready, validate_cv_pdfs, mainscripts/verify/verify_meta_descriptions.py_first_group, extract, check_file, mainscripts/verify/verify_cv_pdf_text.pypdftotext, check_pdf, main
7.8. Database and persistence
7.9. External integrations
HTTP clients
Hosts named in the code
antoineboucher.info4 filesscripts/ci/verify-deploy-lychee.sh:17www.sitemaps.org2 filesscripts/deploy/merge_root_sitemap.py:16cdn.clustrmaps.com1 filesscripts/html/patch_cv_html.py:152mapmyvisitors.com1 filesscripts/html/patch_cv_html.py:22
7.10. Stack and dependencies
Python requirements.txt 3 runtime
Node.js hugo/package.json 5 dev
Node.js tools/medium-mirror/package.json 4 runtime
External dependencies
12 declared packages (7 runtime, 5 development) in requirements.txt, hugo/package.json, tools/medium-mirror/package.json.
Package table 12
| Package | Version | Scope | Purpose | Registry |
|---|---|---|---|---|
typer | >=0.9.0 | runtime | Command line | pypi.org |
rich | >=13.0.0 | runtime | Command line | pypi.org |
tqdm | >=4.66.0 | runtime | Command line | pypi.org |
@tailwindcss/cli | ^4.1.18 | development | User interface | npmjs.com |
@tailwindcss/typography | ^0.5.16 | development | User interface | npmjs.com |
prettier | ^3.4.2 | development | Linting and formatting | npmjs.com |
prettier-plugin-go-template | ^0.0.15 | development | Linting and formatting | npmjs.com |
tailwindcss | ^4.1.18 | development | User interface | npmjs.com |
cheerio | 1.0.0-rc.12 | runtime | Scraping and parsing | npmjs.com |
playwright | ^1.49.0 | runtime | Testing | npmjs.com |
turndown | ^7.2.0 | runtime | A library that converts HTML to Markdown | npmjs.com |
turndown-plugin-gfm | ^1.0.2 | runtime | Turndown 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
| Workflow | Triggers | Jobs | Publishes to |
|---|---|---|---|
Compile LaTeX CV.github/workflows/compile-cv.yml | push, manual run |
| — |
Deploy to GitHub Pages.github/workflows/deploy.yml | push, manual run |
| GitHub Pages |
Lighthouse CI.github/workflows/lighthouse.yml | push, pull request, manual run |
| — |
Link check.github/workflows/link-check.yml | push, pull request, manual run, schedule |
| — |
Quality checks.github/workflows/quality.yml | push, pull request, manual run |
| — |
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
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
- Docker image ×2
- Docker Compose stack
- Vercel
- Kubernetes manifests ×19
- Static site generator
- CI deploy workflow ×3
Published to
Compose services
cv-site linktree-site traefik
Docker base images
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
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
- antoinebou12. (2026, November 5). CV. [Software repository] github.com.
- antoinebou12. (2026, November 5). CV: README. [Repository documentation] github.com.
- antoinebou12. (2026, November 5). scripts/deploy/build_docs.py. [Source file] github.com.
- antoinebou12. (2026, November 5). scripts/build/render_resume_md.py. [Source file] github.com.
- antoinebou12. (2026, November 5). scripts/build/generate_aeo_content.py. [Source file] github.com.
- antoinebou12. (2026, November 5). hugo/hugo.toml. [Source file] github.com.
- Boucher, A. (2026, October 24). Website refonte with Hugo (part 2). [Project article] antoineboucher.info.
- 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.