Repository navigation
Releases: KeeGooRoomiE/cv_hub
Release list
v1.6.0
ATS-Safe Resumes, Fork Onboarding & Astro 7
The largest release so far, and the first one aimed less at this deployment than at whoever forks it. Fork onboarding, custom domains, a second ATS-oriented resume variant and structured data — plus the framework jump to Astro 7 and a batch of meta-tag bugs that had been quietly breaking every social preview the site ever produced.
The problems it solves: A fresh fork started life as someone else's resume — the author's CV, showcase and case-study data had to be found and scrubbed by hand. A fork couldn't serve from its own domain: site and base were derived from GITHUB_REPOSITORY alone, so a custom domain broke canonical links, the sitemap and every OG URL. The only PDF was two-column, and multi-column layouts are the most common cause of scrambled text in ATS parsers — the file most likely to be uploaded to a job portal was the one most likely to be misread. Four equal-weight download buttons offered no obvious "just give me the resume". Social previews never rendered at all, because og:image omitted the base path and 404'd on every page, while canonical URLs carried a literal double slash. Search engines saw one generic description across twenty pages, no structured data, and no hreflang on a site that ships two languages. Printing produced a dark-theme screenshot. And Astro 5 carried 15 open npm advisories.
How it works
npm run init — one-time onboarding for a fresh fork. Backs up and clears the repo's own CV, showcase and case-study data, resets multi-profile to a single default, and reseeds from docs/examples/*, so a new user edits a blank placeholder instead of someone else's resume. Interactive prompts for name/title/language, --dry-run to preview, --force to re-run. No new dependencies — node:readline/promises.
ATS-safe PDF — resume:pdf now renders a second, single-column PDF (resume_{lang}[_{spec}]_ats.pdf) from the same CV data, alongside the existing two-column one. Plain Arial/Helvetica, standard section headings, contacts in the body flow, no icons — reading order in the file matches visual order, top to bottom. The polished two-column version stays the default for human readers.
site.yml — a new deployment-wide settings collection, decoupled from profile and language. Its downloads field controls which download buttons appear and in what order (default [pdf, docx]), with PDF as the single solid primary button and everything else secondary. The formats split by audience: PDF and DOCX are what a visitor recognizes, ATS-PDF and TXT are mainly the owner's own tools. A demo deployment can opt into a grouped form — [{group: people, items: [pdf, docx]}, {group: ats, items: [pdfAts, txt]}] — to show all four under labeled headings. The qualifier lives on the group heading, never on the button label, which is what keeps a one-word button next to a one-word button.
Custom domain — SITE_URL and BASE_PATH env overrides layer on top of the GITHUB_REPOSITORY-derived defaults. Combined with a public/CNAME file, a fork serves from its own domain instead of the default project-page URL.
Structured data — schema.org/Person JSON-LD on CV pages, built from data the page already parses: job title, summary, sameAs from contact links, knowsAbout from skills. hreflang alternates reuse the language-switcher data, scoped per page to the languages that actually have content.
Print — @media print remaps the root color tokens to print-safe values and hides nav, footer, animated background and download buttons. It reuses the token-remap trick the theme system already relies on, so every component inherits it for free.
Astro 7 — up from Astro 5, bringing Vite 8 and closing every outstanding advisory. Collections migrated to the Content Layer with explicit glob() loaders; all 20 pages were diffed against the Astro 5 build and render byte-identically. Node 24 is now required locally.
What's new
- ATS-safe PDF — second, single-column
resume_{lang}[_{spec}]_ats.pdfgenerated from the same CV data; single column, standard headings, contacts in the body flow, no icons npm run init— clears the repo's own CV/showcase/case-study data (backed up first, git history untouched) and reseeds fromdocs/examples/*;--dry-run,--forcesrc/content/site/site.yml— deployment-wide settings collection.downloadssets which buttons show and in what order, flat or grouped by audience; group headings translate viatranslations.yaml(cv.downloads_{group})- Download button hierarchy — PDF is the one solid button, everything else is a ghost button. Where two buttons share a visible label, each gets a distinct
aria-label("Resume PDF" / "ATS-optimized PDF") - Custom domain support —
SITE_URL/BASE_PATHoverrides pluspublic/CNAME - JSON-LD
schema.org/Personon CV/profile pages, andhreflangalternates on CV pages, the showcase list and case studies @media print— printing or saving to PDF from the browser now produces a clean document- Opt-out "Made with CV Hub" footer credit (
site.yml'sfooterCredit, on by default) next to the GitHub link. Unlike the rest of the footer it always points upstream, so a deployed fork stays a discoverable backlink; suppressed automatically on the upstream repo's own deployment, where it would duplicate the GitHub link /changeloglinks out to the fullCHANGELOG.mdand to Releases — the on-site version is a curated distillate, and a curated page with no route to the full log reads as "the project barely changes"- Per-language OG images —
generate-og-image.mjsscreenshots one/og-preview/{lang}route per configured language through Playwright and frames each into a 1200×630 card from the real default-profile CV, not mock data. Supports--themeand--wallpaper; regenerated every build, never committed - YouTube in case-study video blocks — a
youtube.com/watch,youtu.beor/embedURL renders a responsive 16:9 iframe instead of a local<video> codecontent block — verbatim monospace for terminal commands and short snippets, no highlighting engine by design- Block anchors — any
text,image,videoorcodeblock acceptsanchor: "id"for deep links like/showcase/{slug}#quickstart, offset for the sticky header - Inline code in block prose — backtick spans in
title,subtitle,body,bulletsandcaptionrender as styled inline code via a sharedInlineTextcomponent - Video covers on showcase cards — an autoplaying, looping, silent
type: videocover as a lighter replacement for a heavy GIF /quickstartand/get-started— short redirects to the quickstart section for release announcementsnoindexon the 404 page
Changed
- Upgraded to Astro 7 (from 5) — Vite 8, and
npm auditnow reports 0 vulnerabilities, down from 15 - Content collections migrated to the Content Layer —
src/content/config.tsreplaced bysrc/content.config.ts, each collection switched from the removedtype: 'data'to an explicitglob()loader. All 20 pages verified byte-identical against the Astro 5 build - Node 24 is now required locally, matching
.nvmrc,enginesand the CI runner — Astro 7 dropped Node 20 - The on-site
/changelogis now a curated distillate ofCHANGELOG.mdrather than a line-for-line copy. This file remains the full technical record; the selection filter lives inCLAUDE.md HomePage.astroreads thesitecollection itself instead of taking four download URLs threaded through as props fromindex.astro/[...slug].astro
Fixed
og:image/twitter:imagepointed at the wrong URL on every page — the meta tag never includedbase, so it resolved to{owner}.github.io/media/og-image.pngand 404'd. Social previews have been image-less this whole time because of it- Canonical, OG and Twitter URLs carried a literal double slash (
https://…github.io//cv_hub/…) —siteUrlis now derived from Astro's ownAstro.siteinstead of being hand-rolled fromGITHUB_REPOSITORY - Footer
GitHublink and byline URL were hardcoded to the original repo — now derived fromGITHUB_REPOSITORY, so a fork's footer points at itself - 404 page wrapped its own
<html>/<head>/<body>around<Layout>, which already renders a full document — it was missing the site header, nav and footer and carried two competing<title>tags - i18n: the
notfound404translation block was missing from the content schema and silently stripped on load, so the 404 title never resolved - Favicon —
favicon.ico/favicon.svgwere committed but never linked from<head>, and the passive browser fallback missed them under the/cv_hub/base path - Every page shared one generic meta description and OG image — case studies now use their own
tagline, CV pages theirsummary, the changelog its own subtitle; case-study and changelog<title>gained the "— CV Hub" suffix - Case-study hero image loads eagerly with
fetchpriority="high", and case-study images reserve a 16:9 box before loading instead of collapsing to zero height - CI: the Telegram deploy notification no longer reports a cancelled run as a failed build —
deploy.ymlskips the notification whenconcurrency: cancel-in-progresssupersedes a run resume-import-json.mjsandresume-import-linkedin.mjsprinted usage text referencing npm scripts that don't exist;resume-import-linkedin.mjsalso wrote its output todocs/instead ofpublic/downloads/json/, risking collision with the documented example inputs
Removed
public/themes/*.cssuntracked from git — a mechanical copy ofsrc/styles/themes/*.cssregenerated on every build, not a source file- ~5.1 MB of orphaned media — stale cover-image variants referenced by no YAML, plus a duplicate
diceroll/folder ...
v1.5.5
CI Pipeline, Video Blocks & Build Hardening
Infrastructure-heavy release. One new content feature (case-study video), one security fix (PDF injection), and the rest is CI/build plumbing that should have existed from the start.
The problems it solves: Broken builds and malformed YAML could land on main unchecked — nothing ran the generation pipeline on pull requests. Published versions were bare git tags with no CV documents attached. Dependency updates were merged blind. The deploy build was a single opaque step that gave no hint which stage failed. PDF export interpolated raw CV fields straight into HTML, so a stray < or & in a company name or bullet could break or inject into the generated document. Case studies could only show static images.
How it works
CI workflow (ci.yml) — every pull request now runs the full pipeline: merge → DOCX/TXT → PDF → Astro build, and uploads the generated resumes and the site as downloadable artifacts. A broken build or bad YAML fails the PR instead of reaching main.
Release workflow (release.yml) — publishing a GitHub Release regenerates the resume documents and attaches all PDF/DOCX/TXT files to it, so every version is a self-contained CV snapshot.
Dependabot — weekly grouped npm updates and monthly GitHub Actions updates. Every update PR goes through the CI pipeline instead of being merged unverified.
Case-study video block — a type: video content block: a silent autoplay loop for short clips, or poster + controls for longer ones.
PDF export now HTML-escapes every interpolated CV field (company names, bullets, contacts, skills) before it hits the template.
Deploy build split into named per-stage steps (merge / DOCX+TXT / PDF / Astro) — same runner and cost, but the Actions UI now shows per-stage timing and points at the exact stage that failed.
What's new
Case-study video block — type: video content block; silent autoplay loop (short clips) or poster + controls (longer clips)
CI workflow (ci.yml) — PRs run the full generation pipeline and upload the resumes and site as downloadable artifacts, catching a broken build or malformed YAML before main
Release workflow (release.yml) — publishing a GitHub Release regenerates resume documents and attaches all PDF/DOCX/TXT files to it
Dependabot — weekly grouped npm updates, monthly GitHub Actions updates; every update PR is verified by CI
Node version pinned via .nvmrc and package.json engines (>=24), matching the CI runner
Changed
CI: GitHub Actions runner upgraded to Node 24
package.json version synced to the changelog version — was stuck at 0.0.1 while the project shipped 1.5.x
CI: deploy build split into named per-stage steps (merge / DOCX+TXT / PDF / Astro) — per-stage timing in the Actions UI, failing stage identified directly
CI: PDF export now drives the runner's preinstalled Google Chrome (channel: 'chrome') instead of downloading Playwright's chromium — removes the cdn.playwright.dev download that was stalling and hanging deploys; the Playwright browser-cache step was dropped. Local builds still use Playwright's bundled chromium
Responsive breakpoints consolidated from seven ad-hoc values to two — 768px (desktop/mobile base: header, fonts, paddings, animated background) and 960px (multi-column CV and showcase grids); mobile container side padding tightened
Fixed
PDF injection — PDF export now HTML-escapes all interpolated CV data (company names, bullets, contacts, skills); a stray < or & in a field no longer breaks or injects into the generated PDF
Mobile header — the Role dropdown button rendered larger than the nav links (16px vs 14px, wider padding) because a later .dropdown__trigger { font: inherit } overrode the mobile rule; the mobile rule's specificity was raised so the button now matches the links
Removed
Two unused dependencies — hast-util-parse-selector and serve were not imported or referenced by any script
What's Changed
- ci: bump actions/upload-pages-artifact from 3 to 5 by @dependabot[bot] in #7
- ci: bump actions/setup-node from 4 to 7 by @dependabot[bot] in #8
- ci: bump actions/upload-artifact from 4 to 7 by @dependabot[bot] in #9
- chore(deps-dev): bump playwright from 1.58.2 to 1.62.1 in the dev-dependencies group by @dependabot[bot] in #11
- chore(deps): bump the minor-and-patch group with 4 updates by @dependabot[bot] in #12
New Contributors
- @dependabot[bot] made their first contribution in #7
Full Changelog: v1.5.4...v1.5.5
Live demo: https://keegooroomie.github.io/cv_hub/
Full changelog: https://keegooroomie.github.io/cv_hub/changelog
Project Deep Dive: https://keegooroomie.github.io/cv_hub/showcase/cv-hub/en/
v1.5.4
SEO, Lightbox & Infrastructure Polish
Quality-of-life release. No new major features — just fixes that were quietly wrong and infra improvements that should've been there earlier.
The problems it solves: Case Study images had no way to view them full-size. The site wasn't generating a sitemap, so search indexing was blind to profile × language routes. CI was downloading a separate Chromium on every deploy run, stalling deploys. Seven ad-hoc responsive breakpoints made layout behaviour unpredictable. Hover affordance on non-clickable cards was misleading. AnimatedBackground was re-rasterizing on every frame.
How it works
Lightbox is self-contained — click any Deep Dive image, it opens fullscreen. Backdrop click, close button, or Escape to dismiss. No dependencies.
Sitemap is generated by @astrojs/sitemap and covers every profile × language route automatically. robots.txt points to it.
CI PDF export now uses the runner's preinstalled Chrome (channel: 'chrome') — no Playwright browser download, no CDN hang. Local builds still use Playwright's bundled Chromium.
merge.mjs now validates slug === spec on merge — mismatched profile URLs fail fast with a clear message instead of silently desyncing CV files.
What's new
- Click-to-zoom lightbox — fullscreen image view on any Case Study image; close via backdrop, button, or Escape
sitemap.xml— via@astrojs/sitemap; covers all profile × language routesrobots.txt— points to sitemapmerge.mjsslug validation — fails fast whenslug !== spec, prevents silent desync
Changed
- Tags de-emphasized — borders removed, text muted on Platforms/Stack/Tags pills; section hierarchy reads clearer
- CI: Telegram notification uses
envblock for secrets instead of inline interpolation - CI: GitHub Actions runner upgraded to Node 24
- CI: PDF export uses preinstalled Chrome — removes
cdn.playwright.devdownload that was stalling deploys; Playwright browser-cache step dropped - Responsive breakpoints consolidated from 7 ad-hoc values to 2 —
768px(header, fonts, paddings, background) and960px(multi-column grids)
Fixed
- Hover-lift removed from passive cards —
.card:hovertranslate/shadow now only applies to interactive showcase project cards - AnimatedBackground performance — reduced orb blur (80px → 60px), slowed drift cycles, removed
scale()from keyframes; GPU layer is now cached instead of re-rasterized on scroll - Showcase LCP — first card with image cover loads
eagerwithfetchpriority="high"; remaining covers stay lazy - Role dropdown accessibility —
aria-haspopup,aria-controls,aria-expandedadded and synced with open state; stray always-trueactiveclass removed - i18n: Platforms/Stack/Tags/Featured labels on non-default-language showcase cards no longer fall back to English — stray
[lang]index on an already-resolved string was dropping translations - Build robustness: home page now guards missing merged CV artifact with a fallback (matches dynamic profile route)
- Mobile header: Role dropdown button now matches nav link size — specificity fix for
.dropdown__trigger { font: inherit }override
Live demo: https://keegooroomie.github.io/cv_hub/
Full changelog: https://keegooroomie.github.io/cv_hub/changelog
Project Deep Dive: https://keegooroomie.github.io/cv_hub/showcase/cv-hub/en/
v1.5.3
v1.5.3 — Backgrounds, CI & Polish
Minor but meaningful update. CV Hub gets two new animated backgrounds, smarter CI notifications, and several fixes that were quietly annoying.
The problem it solves: the existing AnimatedBackground was the only visual option, CI had a blind spot on build failures, and the role dropdown had a frustrating hover behaviour. The fix — two new canvas-based backgrounds, proper failure coverage in the pipeline, and a click-based dropdown.
How it works
PlayStationWaves and WaveLines are drop-in canvas components — same interface as AnimatedBackground, swap in Layout.astro. Both respond to theme tokens automatically. CI now runs notify_telegram with if: always() so build failures surface immediately. Playwright cache is keyed to package-lock.json — invalidates on dependency changes, transparent otherwise.
Layout.astro → <PlayStationWaves /> or <WaveLines /> → canvas, no JS framework, no dependencies
What's new
PlayStationWaves.astro— XMB-inspired filled sine waves; configurable wave count, speed, amplitude, opacity; time-of-day hue shift; non-deterministic startWaveLines.astro— glowing stroke wave lines with per-line offscreen compositing for correct glow- Telegram notifications now cover build failures — three-branch logic: ✅ deployed, ❌ build failed, ❌ deploy failed; extended with branch and short SHA
- Playwright Chromium cached by
package-lock.jsonhash — ~2 min saved per deploy on cache hit LICENSE— MIT addedARCHITECTURE.md— root-level architecture overviewCHANGELOG.md— root-level changelog, full history from 1.0.0
Fixed
WaveLinesglow compositing — offscreen canvas per line prevents alpha destruction at edges- Sticky header —
html { height: 100% }/body { min-height: 100% }fixes scroll context - Role dropdown — click-toggle with click-outside; no more accidental close on cursor exit
Live demo: https://keegooroomie.github.io/cv_hub/
Full changelog: https://keegooroomie.github.io/cv_hub/changelog
Project Deep Dive: https://keegooroomie.github.io/cv_hub/showcase/cv-hub/en/
v.1.5.2
v1.5.2 — Translation & Share Improvements
Minor but important update. CV Hub now simplifies ProjectCard translations, adds share buttons for Case Study pages, and fixes language handling and mobile performance.
The problem it solves: ProjectCard translations were overly complex, share functionality was missing, and some mobile pages had unnecessary CSS overhead. The fix — simplify translation props, add share button support, and clean up mobile CSS.
How it works
ProjectCard translation props now accept direct strings instead of nested objects, making i18n simpler. Case Study pages with shareable: true in YAML automatically display a share button. Language switching on showcase pages now correctly swaps project translations. Mobile pages have unnecessary CSS removed, improving performance.
projects.yaml + {slug}_{lang}.yaml → /showcase/{slug}/{lang} → ProjectCard translations simplified, share button added
What's new
- ProjectCard translations simplified — direct string props, no nested object required
- Share buttons for Case Study pages —
shareable: truein YAML enables sharing - Language switcher fixed — works correctly on showcase pages for project translations
- Mobile pages optimized — unnecessary CSS rules removed
- ProjectCard props simplified — easier to maintain and extend
Docs
README, ENGINEERING.md, and INFO.md updated to reflect simplified translation props, share button usage, and mobile optimizations.
Live demo: https://keegooroomie.github.io/cv_hub/
Full changelog: https://keegooroomie.github.io/cv_hub/changelog
Project Deep Dive: https://keegooroomie.github.io/cv_hub/showcase/cv-hub/en/
v1.5.1
v1.5.1 — Case Studies & Language Fixes
The big one. CV Hub now supports per-project Case Study pages and fully language-aware navigation, while fixing mobile layout, links, and routing issues.
The problem it solves: previously, Showcase was mostly preview-only, case studies weren’t fully structured, and multi-language navigation was unreliable. The obvious fix — make deep-dive pages, block-based content, and correct all navigation. The engineer’s fix — extend block system, fix routing, and clean up mobile layout.
How it works
Each project can now have its own Case Study page, built from flexible text, image, divider, and links blocks. Project cards automatically link to their deep-dive pages. URLs respect language, archive, and featured flags, and navigation buttons preserve language context. Mobile layout automatically applies proper padding and spacing.
projects.yaml + {slug}_{lang}.yaml → /showcase/{slug}/{lang} → links respect BASE_URL
What's new
- Case Study pages — dedicated per-project pages with flexible content
- Block-based content system — supports
text,image,divider,linksfor storytelling - Full project narratives — architecture, decisions, and outcomes included
- Showcase deep-dive pages — static, Notion-like, fully controlled
- Per-project routing — dynamic URLs for every case study
- Showcase transformed — from preview-only to entry point for detailed project pages
- Language switcher fixed — works correctly on Showcase list and Case Study pages
- Navigation links fixed — back button and Showcase nav preserve language
- Project card links fixed — respect
BASE_URL, no hardcoded/cv_hub/ - Mobile layout fixed — horizontal padding applied correctly
- Showcase slug setup corrected — for archived and featured projects in other languages
Docs
README, ENGINEERING.md, and INFO.md fully updated to cover Case Study pages, block-based content, routing, and i18n improvements.
Live demo: https://keegooroomie.github.io/cv_hub/
Full changelog: https://keegooroomie.github.io/cv_hub/changelog
v1.4.0
v1.4.0 — Multi-profile system
The big one. CV Hub now supports multiple role-specific CV versions generated from a single YAML source.
The problem it solves: HR feedback kept saying "too much GameDev in your DevOps resume". The obvious fix — maintain separate resumes. The engineer's fix — build a merge pipeline and generate them automatically.
How it works
One base YAML + delta files per profile. merge.mjs combines them before build. The site generates separate pages, and the build pipeline generates separate PDF/DOCX/TXT files for each combination of profile × language.
en.yaml + en_devops.yaml → /devops → resume_en_devops.pdf
en.yaml + en_gamedev.yaml → /gamedev → resume_en_gamedev.pdf
What's new
- Multi-profile routing —
/devops,/gamedev,/devops/ruetc. via[...slug].astro - merge.mjs — YAML merge pipeline with whitelist-based experience filtering
- profiles.yml — optional profile registry, graceful fallback if absent
- languages.yml — dynamic language config, any number of languages
- i18n system —
translations.yaml+makeT()helper with fallback chain - Profile dropdown in header (Role ▾)
- Per-profile documents — PDF/DOCX/TXT generated for every profile × language combo
- Dynamic siteUrl — resolved from
GITHUB_REPOSITORY, forks work without config - 404 page — redirects to main
Removed
ru.astroandshowcase/ru.astro— replaced by[...slug].astro
Docs
README, ENGINEERING.md and INFO.md fully updated. INFO.md now has a complete field reference, routing table, merge rules, and i18n guide.
Live demo: https://keegooroomie.github.io/cv_hub/
The changelog is hidden in plain sight at /changelog — versioning the tool itself felt appropriate.
v1.3.0 — Feature complete initial release
CV Hub v1.3.0
First fully featured release of CV Hub — Resume as Code.
What's included
Core
- YAML-driven CV site with single source of truth
- Two languages — EN / RU
- Automated export to PDF (Playwright), DOCX, TXT at build time
- GitHub Actions CI/CD — deploys on every push to
main
Site
- Main CV page
- Showcase page with featured / regular / archived project cards
- Changelog page — version history of the project itself
- Animated background — CSS-only, theme-aware, respects prefers-reduced-motion
Themes
- 4 ready-made themes:
frosted,light,nordic,peachy - URL-based theme switching —
?theme=peachy, no rebuild required - Token-based CSS — one
:rootblock controls the entire site
Meta & SEO
- OpenGraph + Twitter Card meta tags
- Lighthouse: Performance 100 / Accessibility 100 / Best Practices 96 / SEO 100
Developer experience
- LLM-assisted YAML generation via
docs/llm-resume-guide.md - JSON Resume import (
resume:import) - LinkedIn PDF parser (
resume:linkedin) - Full documentation: INFO.md, ENGINEERING.md, BKG_INFO.md
Resume data
Last updated: 2026-03-06