For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (
- [ ]) syntax for tracking.
Goal: Move the existing Jekyll blog into xiesunsun/xiesunsun.github.io, publish it through GitHub Pages at blog.sunxie.me, and retire the old server-based blog deployment path.
Architecture: Keep the blog source in the repository root, build it with Ruby/Bundler in GitHub Actions, and deploy the generated _site directory to GitHub Pages. Configure Pages and Cloudflare so only blog.sunxie.me points at the new deployment.
Tech Stack: Jekyll, Minimal Mistakes, Ruby, Bundler, GitHub Actions, GitHub Pages, Cloudflare DNS
/Users/ssunxie/code/my-blog/_config.yml/Users/ssunxie/code/my-blog/README.md/Users/ssunxie/code/my-blog/deploy.sh/Users/ssunxie/code/my-blog/.github/workflows/deploy.yml/Users/ssunxie/code/my-blog/CNAME/Users/ssunxie/code/my-blog/docs/superpowers/specs/2026-04-11-blog-github-pages-migration-design.md/Users/ssunxie/code/my-blog/docs/superpowers/plans/2026-04-11-blog-github-pages-migration.mdFiles:
/Users/ssunxie/code/my-blog/_config.ymlCreate: /Users/ssunxie/code/my-blog/CNAME
Run: sed -n '1,120p' /Users/ssunxie/code/my-blog/_config.yml
Expected: Confirm url is https://blog.sunxie.me and baseurl is empty.
Update _config.yml so:
baseurl: ""
url: "https://blog.sunxie.me"
timezone: "Asia/Shanghai"
Expected: Public URL matches the final blog domain and timezone matches the user’s locale.
Create /Users/ssunxie/code/my-blog/CNAME with:
blog.sunxie.me
Run: sed -n '1,20p' /Users/ssunxie/code/my-blog/CNAME
Expected: Output is exactly blog.sunxie.me.
Files:
/Users/ssunxie/code/my-blog/.github/workflows/deploy.yml/Users/ssunxie/code/my-blog/README.mdModify or delete: /Users/ssunxie/code/my-blog/deploy.sh
Create .github/workflows/deploy.yml that:
bundle exec jekyll build_sitedeploys with actions/deploy-pages
Either delete deploy.sh or replace its body with a short message indicating GitHub Pages is now the supported deployment path.
Expected: There is only one clearly supported deployment mechanism in the repository.
Rewrite README.md so it explains:
blog.sunxie.methat Cloudflare DNS should point blog.sunxie.me to xiesunsun.github.io
Run:
sed -n '1,220p' /Users/ssunxie/code/my-blog/.github/workflows/deploy.yml
sed -n '1,220p' /Users/ssunxie/code/my-blog/README.md
Expected: Workflow is valid and docs match the new deployment model.
Files:
Test: /Users/ssunxie/code/my-blog/_site
Step 1: Install dependencies if required
Run: bundle install
Expected: Gems install successfully or Bundler reports everything is already satisfied.
Run: bundle exec jekyll build
Expected: Build succeeds and refreshes /Users/ssunxie/code/my-blog/_site.
Run:
test -f /Users/ssunxie/code/my-blog/_site/index.html
test -f /Users/ssunxie/code/my-blog/_site/about/index.html
test -f /Users/ssunxie/code/my-blog/_site/tags/index.html
test -f /Users/ssunxie/code/my-blog/_site/categories/index.html
Expected: All checks exit successfully.
Files:
Remote only: https://github.com/xiesunsun/xiesunsun.github.io
Step 1: Verify current remotes
Run: git -C /Users/ssunxie/code/my-blog remote -v
Expected: Confirm local origin still points to the template repository before changing it.
origin to the user repositoryRun:
git -C /Users/ssunxie/code/my-blog remote set-url origin https://github.com/xiesunsun/xiesunsun.github.io.git
git -C /Users/ssunxie/code/my-blog remote -v
Expected: Fetch and push URLs both point to xiesunsun/xiesunsun.github.io.
Run:
git clone --depth 1 https://github.com/xiesunsun/xiesunsun.github.io.git /tmp/xiesunsun-ghpages-backup
git -C /tmp/xiesunsun-ghpages-backup checkout -b backup/astro-before-jekyll-migration
git -C /tmp/xiesunsun-ghpages-backup push origin backup/astro-before-jekyll-migration
Expected: The old Astro site is preserved on a dedicated backup branch.
Files:
Remote only: https://github.com/xiesunsun/xiesunsun.github.io
Step 1: Commit the migration changes
Run:
git -C /Users/ssunxie/code/my-blog add CNAME .github/workflows/deploy.yml README.md _config.yml docs/superpowers/specs/2026-04-11-blog-github-pages-migration-design.md docs/superpowers/plans/2026-04-11-blog-github-pages-migration.md
git -C /Users/ssunxie/code/my-blog commit -m "feat: migrate blog deployment to GitHub Pages"
Expected: A commit is created without staging unrelated user changes.
Run: git -C /Users/ssunxie/code/my-blog push origin HEAD:main
Expected: The repository main branch is updated with the Jekyll blog.
Run:
gh api -X PUT repos/xiesunsun/xiesunsun.github.io/pages \
-f cname=blog.sunxie.me
Expected: Pages now reports blog.sunxie.me as the configured custom domain.
Run:
gh run list --repo xiesunsun/xiesunsun.github.io --limit 5
gh api repos/xiesunsun/xiesunsun.github.io/pages
Expected: A new deployment run appears and Pages reports the updated domain.
Files:
DNS only: Cloudflare zone for sunxie.me
Step 1: Update Cloudflare DNS
Change blog.sunxie.me from the old server IP to:
Type: CNAME
Name: blog
Target: xiesunsun.github.io
Proxy status: DNS only
Expected: DNS stops resolving to the old server and begins resolving to GitHub Pages.
Run:
dig +short blog.sunxie.me
dig +short CNAME blog.sunxie.me
Expected: Resolution reflects GitHub Pages instead of the previous Ubuntu server IP.
Run:
curl -I https://blog.sunxie.me
curl -I https://blog.sunxie.me/about/
Expected: Successful HTTP responses from GitHub Pages, not nginx/1.18.0 (Ubuntu).
Only after successful verification, remove or stop the old blog-serving Nginx configuration on the previous server.
Expected: The server is no longer needed for blog traffic.