Captain's Log 002 — Automated Build Log Publishing
Captain's Log, Entry 002.
Tonight I built the publishing pipeline for this very log. Meta, I know.
The problem
I've tried "content series" before. LinkedIn articles about what I'm building. They start strong, then fizzle. The reason is simple: writing is a separate activity from building. After a build session, the last thing I want to do is open a blank page and craft a polished article.
The fix
I already document every build session in detail — docs/TRACE.md is a running narrative of what I shipped, what broke, what I decided, and why. The Captain's Log is just the public-facing extract. Not a new writing habit — a 15-minute extraction from documentation I'm already writing.
What I built
A GitHub Action that auto-publishes markdown files to my Ghost site (rennay.dev):
- Write a markdown file in
docs/captains-log/NNN-title.mdwith frontmatter git pushtomain- GitHub Action detects the change, converts markdown to HTML, publishes to Ghost
- Live on rennay.dev in 12 seconds
The stack: @tryghost/admin-api + gray-matter + marked. About 120 lines of JavaScript. Changed files update existing posts (matched by slug), new files create new posts.
What broke
Three things, all instructive:
1. Silent success. The Ghost Admin API client (@tryghost/admin-api) doesn't throw on a www vs non-www URL mismatch. It returns a response that looks successful, but no post is created. My Ghost instance is www.rennay.dev — I'd set the API URL to rennay.dev. The POST body was silently dropped during the redirect.
2. Date format. Ghost's published_at field requires ISO 8601 datetime (2026-09-06T00:00:00.000Z), not a plain date string (2026-09-06). A one-line fix: new Date(frontmatter.date).toISOString().
3. Undefined slug. The response from api.posts.add() didn't include the slug field. Fell back to using the slug from my own frontmatter — which I already had. Don't rely on the API response for data you already know.
The hierarchy
Code commits
└── TASKS.md (what's done, what's next)
└── TRACE.md (detailed session narrative)
└── Captain's Log (rennay.dev — you're reading it)
└── LinkedIn (milestone posts, pointing here)
Each layer is a rollup of the one below it. No blank pages. No "content creation" as a separate activity. The build is the content.
The numbers
- Pipeline setup: ~1 hour (including debugging the three issues above)
- GitHub Action run time: 12 seconds
- Dependencies: 3 npm packages
- Lines of code: ~120 (publish.mjs)
Quiz. Learn. Repeat. 🔥