Welcome! This repository contains the source for my personal website, which is built and rendered by mehub, a custom Static Site Generator I wrote in Go.
This project demonstrates a complete, end-to-end ownership of a personal platform, from the core rendering engine to the automated CI/CD pipeline that publishes it.
This site was previously built with Astro. I migrated to a custom Go SSG to solve two key engineering challenges:
- Dependency Churn: The
npmecosystem, even with minimal packages, required constant updates. The CI/CD install cycle alone took over 30 seconds. - Performance & Simplicity: I wanted a zero-dependency, single-binary solution. My Go SSG compiles and builds the entire site in under 2 seconds, eliminating
node_modulesand simplifying the entire toolchain.
- Portfolio: Showcasing my projects.
- Blog: Sharing insights, tutorials, and personal thoughts.
- Tags: Organizing content with tags for easy navigation.
- Archives: Exploring past content by year.
- Custom Go SSG: The engine that powers it all.
This site is maintained through a Git-native, mostly automated content pipeline — designed for consistency, safety, and minimal manual work. All changes are validated, then merged with human oversight before going live.
- Go Formatting & Analysis: Enforced automatically via
go fmtandgo vet. - Markdown Consistency: Validated with markdownlint.
Content Automation (blog-specific):
sync-blog-post.yml→ Pulls draft posts from private sources.publish-blog-post.yml→ Auto-publishes on scheduled UTC date.
CI/CD & General Automation:
ci.yml→ Runs Go formatter checks (go fmt) on every pull request to ensure code quality.- Vercel Deployment → Automatically builds and deploys the Go SSG on every push to
main(Zero-Config deployment). markdownlint.yml→ Checks Markdown files for style violations.label-based-merge.yml→ Auto-merges PRs when labeled (e.g., forgo.modupdates) after passing all checks.
I manually review all blog content before merging — via GitHub UI, CLI, or label — to verify formatting, clarity, and intent. Only low-risk changes (like dependency updates) are auto-merged.
sync_blog_post.sh→ Syncs content across repositories or branches.publish_blog_post.sh→ Finds posts withdraft: trueand removes the flag only if the current UTC date matchespublishDate.
Philosophy: Automate repetition. Preserve judgment.