Releases: mathewmusango/my-portfolio
Releases · mathewmusango/my-portfolio
Release list
Release v3.3.0
Added
- "The Platform Behind This Site" project page — first entry under Projects (en/es/zh): prose-first case study of the platform (architecture, delivery model, CI/CD, governance, security, real incidents) with GitHub references (#49).
- Site Atlas — Platform Architecture page — the four explored diagrams on-site (site delivery, visitor metrics, Terraform control plane, how a change ships), separate from the zoomable Site Structure map (#50, folded into #53).
- Structure-map rectification — Site Metrics submenu shows its real shape (default → Visitor Analytics → CloudFront → API → writer/reader → DynamoDB); the AWS metrics backend renders inside its own theme-aware subgraph; Projects gains the new page's node (#49/#50/#53).
- Release timeline generated from CHANGELOG —
scripts/releases_hook.pybuilds the rows at compile time (no drift); onv*tag builds the hook promotes the[Unreleased]content into the tag's version so prod shows the just-released release; the Site Atlas landing lists the latest 10, the full archive stays reachable (#49/#50/#53). - Branch + tag rulesets as code —
main(PR-only, strict, no bypass) andv*tag rulesets defined in exportable JSON and applied viagh api; enforcement verified and recorded beside the configs (#25/#35, #36/#38, #37/#39, #40/#41). - Curated labels + template taxonomy — five per-surface labels (
ci·infra·security·governance·dependencies), PR template ↔ label mapping, 7-part issue structure documented (#11, #15, #18, #26/#27).
Changed
- Docs split into system + implementation views — root README slimmed to the system view;
.github/workflows/README.mdis the CI/CD implementation reference;terraform/README.mdaudited for accuracy (#23/#28, #24/#34). - Check names are the gate names — CI reports job names (
ci-build,checks-<surface>-<tool>) so rulesets require exactly what runs; per-surface checks self-gate on changed paths (skip-model), skipping and reporting success when untouched (#12, #17). - Prod deploy split —
v*deploys to pre-prod (AWS mirror) then gated prod (GitHub Pages via the official Pages actions); OIDC trust extended for environment-bearing deploy jobs (#20, #22). - Staging content-hash skip — byte-identical artifacts skip sync + invalidation via marker objects (existence-checked — no extra IAM needed) (#29/#30, #31/#32).
- Local check driver —
scripts/check_local.sh: default runs every surface whose files changed (diff-gated, mirroring CI),--fullfor a whole-repo pass, per-language selection;check-compose.yamlservices fixed so every local check is runnable and truthful (#52).
Fixed
- Local checks were silently checking nothing — docker-compose interpolated
$fat parse time (empty filenames) and the trailingecho okmasked failures; escaped with$$fand made per-file failures fail the service (#52). - Broken CJK heading anchor — zh project page's in-page link pointed at a slug the theme never generated; pinned an explicit
{#delivery-model}anchor across locales (#49/#50/#53).
Dependencies
Release v3.2.0
Added
- Local HTTPS dev server — one mkcert root CA per machine (
certs/gitignored);serve.pyTLS flags;compose.yamlcert mount + https-first healthcheck. Per-project certs for*.mathewmusango.test. - GitHub release badge in the repo README (latest release incl. pre-releases).
Changed
- Title standardized to "Platform Engineering Manager" across the site (about tagline en/es/zh + meta description) — previously "…and Infrastructure Leader".
- Resume PDFs updated in all three locales (headline:
Senior Platform Engineer · Tech Lead, Platform Engineering). - Deploy workflows deploy on every successful CI build — the site-changes gate (which only diffed
HEAD~1..HEAD) is removed. - CloudFront toggle is staging-only (prod has no toggle role).
Fixed
- Site bucket SSE reverted to AES256 (
aee25c6): SSE-KMS (even the AWS-managed key) is incompatible with CloudFront OAC — CloudFront can't getkms:Decrypt, so a content deploy after the KMS change made the staging site 403 on every object (prod would have hit the same on its next deploy). The state bucket keeps KMS (not OAC-served). Checkov CKV_AWS_145 is satisfied by AES256. - Deploys no longer skip on multi-commit batches (
1bf9bd9): the deploy gate diffed onlyHEAD~1..HEAD, so a batch whose last commit wasn't a site change never deployed — staging went stale.
Release v3.1.1
Security
- IAM hardening: the CI terraform role's IAM is scoped — role/policy management on project resources only;
iam:PassRolelimited to the two Lambda roles with a service condition (privilege-escalation vector closed). - S3 encryption: site + state buckets now use KMS (
aws:kms, AWS-managed key — zero cost, no CMK). - Security headers at the edge: a CloudFront response-headers policy (nosniff, frame-DENY, referrer, HSTS) is attached to both distributions.
- TLS 1.2+ pinned explicitly on both CloudFront distributions.
- Static security scanning (Checkov) in CI — every finding is fixed or annotated with the reason (Free-Tier constraint, public-by-design, AWS limitations).
Changed
- Terraform static checks (fmt / validate / tflint / checkov) run in CI on every terraform change.
- S3-native state locking (
use_lockfile) replaces the deprecated DynamoDB lock config. terraform/cistate moved to S3 (per-env bucket,ci/key) — no more local-only state.- CloudFront invalidation: shared
scripts/invalidate-cloudfront.sh+ manualinvalidate.ymlworkflow; deploys invalidate inline after each sync. - CI workflow concurrency guard per environment.
Fixed
- Reserved concurrency reverted — the account's Lambda concurrency limit (10) makes it impossible (annotated accept).
- Lambda/CloudFront permission gaps in the CI role closed (concurrency + response-headers-policy actions).
Release v3.1.0
Fixed
- Language switcher on the AWS sites — the switcher now works on every page: root pages' language links (which carried the gh-pages
/my-portfolio/base) are rewritten for root-hosted deployment, and subpages' page-relative links pass through unchanged. - Directory URLs without a trailing slash (
/es/about) now resolve correctly on CloudFront + S3 instead of 404. - 404 page — language switcher links and the Home button now point at the current host's root (they were baked to
/my-portfolio/).
Release v3.0.1
Changed
- Bootstrap drift guard:
terraform/cinow carries a warning that the CI roles/policies only reach AWS whenscripts/bootstrap-aws.sh <env>is re-run — after anyterraform/cichange, re-run it for both environments (prod's role policy had drifted one run behind and failed the prod apply ondynamodb:UpdateTimeToLive). - Versioning semantics documented: tag-and-release policy (site-input deploy gate, MINOR/MAJOR/PATCH meanings) recorded in the project skill + private guide.
- Docs: README + terraform README synced to the current architecture (metrics live on both environments, injected deployment values, single-repo flow).
Release v3.0.0
Added
- AWS platform (staging + prod) — the site now runs on real infrastructure: a private S3 bucket behind CloudFront (OAC) serving at
/, with staging (main pushes) and prod (v*tags) environments. - Three deploy targets: staging S3 on
main, prod S3 + GitHub Pages onv*tags — deploys gate ondocs//overrides//mkdocs.ymlchanges. - Live visitor analytics (both environments): CloudFront (geo headers) → API Gateway → Lambda (reader/writer, least-privilege IAM) → DynamoDB (90-day TTL) — the Site Metrics dashboard now shows real data.
- Free edge origin-gate (CloudFront Function): only the site may call the metrics API — WAF-equivalent at $0.
- Localized error pages (403/404 →
/404.html, 500 → language-matched page) and directory-URL resolution (/path/→/path/index.html) on CloudFront.
Changed
- Terraform value hygiene — zero static values in code:
project,environment,aws_region,allowed_origin, andtagsare injected at runtime (CI secrets / local tfvars); the WAF host is derived fromallowed_origin. - Per-environment least-privilege roles (terraform vs deploy) and state-based OIDC provider ownership.
- Language switcher fixed on all hosts (relative links — dev server, S3, CloudFront).
- Metrics endpoint per target — staging and prod each bake their own beacon endpoint at build time.
Fixed
- 404s on CloudFront + S3 from directory URLs and non-root path layouts.
- Metrics beacon fetch failing with schemeless endpoints — endpoints are now configured with the full
https://URL.
Release v2.5.0
Added
- Glossary tooltips: technical acronyms (AWS, PCI-DSS, CI/CD, LCP, INP, CLS, SBOM, …) now show a hover tooltip with their meaning — site-wide, in all three languages.
Changed
- Release Timeline: now sortable by version (dot-aware ordering) via a self-hosted tablesort, plus a primary "View all releases" button.
- Home CTAs: "Contact Me" is a primary button linking to the Contact page, the home buttons gained icons, and the redundant "Connect via LinkedIn" button was removed.
- Error pages: the 404 and 500 "Home" / "Contact Me" buttons are now primary with white icons, matching the home page.
Fixed
- Punctuation: the About languages line and the Projects index descriptions now end with a period in all three languages.
Release v2.4.0
Added
- Site Structure page (Site Atlas menu, trilingual): interactive mermaid site-map — self-rendered with the site theme (light/dark aware), node labels localized per language, hover preview cards, clickable nodes that open pages in a new tab, and inline zoom controls.
- Site Atlas submenu: the single page split into a landing (intro + The Repository), Release Timeline, and Tags index — a collapsible menu like Home.
- Mermaid self-hosted (mermaid@11.17.1) — diagrams render without runtime CDN requests.
Changed
- Breadcrumbs: each tab root shows its own name; the Home crumb appears only for Home-section pages; tab-root duplicates removed (no more "Site Atlas › Site Atlas").
- Typography: balanced heading line breaks and no orphaned body words site-wide.
- Site Structure URL moved under
/atlas/structure/(folder-style, like Tags).
Release v2.3.0
See CHANGELOG.md for details.
Release v2.2.0
Added
- i18n folder structure: pages now live in
docs/en/,docs/es/,docs/zh/(was flat*.es.md/*.zh.mdsuffix naming) — rendered URLs unchanged. - Localized error pages:
500page translated per language (/500/,/es/500/,/zh/500/), and the404page is JS-localized from the URL prefix (/es/,/zh/) since it's a single static template. - Real issuer logos for the two Coursera certifications: official Google wordmark and the official CU Boulder interlocking mark (replacing placeholder icons).
- JS/CSS minification (
mkdocs-minify-plugin) alongside HTML — custom scripts listed injs_files/css_files(already-minified pdf.js excluded). - Translation staleness check in CI: an English page committed after its
es/zhtranslation fails the build until the translation is updated (git commit timestamps). site_urlcanonical config: sitemap, canonical links, and hreflang alternates now correct in every build (previously only prod CI injected it; local/test builds emitted a brokenNonesitemap).- In-depth documentation:
MKDOCS.md(mkdocs.yml reference) and refreshedREADME.md;DEVOPS.mdupdated.
Changed
check_translations.pynow enforces presence and staleness (heading drift remains a warning).- The shared build action only injects
site_urlwhen the config key is absent.
Fixed
404page broken rendering (a stray</script>corrupted the localization script — replaced the fragile regex with string matching).docs/assets/pdf-viewer.htmlnow references the minified viewer script.