📦New post: The Last Mile of Shipping Is the Hardest PartRead now →
← Back to Blog

The Last Mile of Shipping Is the Hardest Part

The code is merged. The feature works. And now you're staring at 12 manual steps. Here's how I turned that last mile into a system.

The Last Mile of Shipping — release workflow diagram showing PLAN, BUILD, SHIP, MARKET, COMPOUND phases

If you've shipped software alone, you know the feeling. The code is merged. The feature works. And now you're staring at a list of 12 manual steps standing between you and the release.

That's where things break.

I built a macOS menu bar app and shipped it through five versions in about a week. Version 1.2 alone required two releases: I'd built the DMG, missed the app icon, and run into a binary name collision on the case-insensitive filesystem — 24 manual steps across two attempts. Version 1.3 was worse: four features, one release, version string living in six files. I missed one. Then forgot to update the appcast signature. Existing users got a cryptic "improperly signed" error. Version 1.4: the landing page said v1.3 while the download was v1.4. Not because the code was wrong. Because the release process was manual, and manual processes accumulate errors.

So I turned the manual work into a system.

What I Was Already Using

I'd been using Claude Code with the Compound Engineering plugin for planning and building. It handles the front half of the work well:

  • /brainstorming to explore ideas before committing
  • /ce:plan to write structured implementation plans
  • /ce:work to execute those plans with tests and incremental commits
  • /ce:review for code review
  • /ce:compound to document solutions after fixing hard bugs

The gap was everything that happens after the code is merged. The plugin doesn't cover releasing, marketing, or onboarding contributors. That's the part that kept breaking.

The Gap

The workflow looked like this:

/brainstorming → /ce:plan → /ce:work → /ce:review → ??? → ??? → ???
Planned workflow vs. what actually happens at ship time — the structured left half gives way to a tangle of manual steps on the right

The "???" was me manually running gh release create, hand-editing appcast.xml, copy-pasting version strings into HTML files, and writing tweets from memory.

Planning and building: structured. Shipping and marketing: fragile.

What I Built

Four slash commands that fill the gap. They live in a separate repo from the Compound Engineering plugin — think of them as the release half of the same workflow.

/release – takes a version number and handles everything:

/release 1.4.0

Pre-flight checks (tests pass? clean tree? on main?). Version bump across all files that mention the version. Changelog generation from git log. Build the artifact. Sign it if Sparkle is configured. Tag. Push. Create GitHub release with the artifact. Deploy the landing page. Close the milestone.

One command instead of twelve.

/announce – generates social media posts from the changelog:

/announce

Reads CHANGELOG.md, extracts the latest version's features, and generates a Twitter post (under 280 characters), a LinkedIn post, a Hacker News "Show HN" submission, and a newsletter template. From real feature descriptions, not corporate filler.

/landing-page – generates a product landing page from the codebase:

/landing-page

Reads your README, package metadata, and CLI help output. Picks a design palette based on the project type. Generates a single self-contained HTML file with Tailwind CSS: hero, terminal demo with real commands, feature cards, getting started guide, FAQ accordion, dark/light mode. No build step needed. Run it once when the project is ready for a public face — not on every release.

/contribute – generates CONTRIBUTING.md by analyzing the codebase:

/contribute

Detects your language, build commands, test framework, commit conventions, and linter. Writes a contributing guide with actual commands from your project, not generic boilerplate. Verifies the commands work before writing the file. Like /landing-page, this is a one-time setup artifact — but it belongs in the same phase because both reduce future friction by making the project legible to others.

The Workflow Now

/brainstorming → /ce:plan → /ce:work → /ce:review → /release → /announce
                                                                    ↑
                                                              /landing-page (one-time)

Five phases, all covered:

  1. Plan: /brainstorming/ce:plan
  2. Build: /ce:work/ce:review
  3. Ship: /release
  4. Market: /announce + /landing-page
  5. Compound: /ce:compound + /contribute

Each phase reads from the one before it. /release reads the changelog /ce:work generated. /announce reads the changelog /release updated. /contribute reads the conventions your code already follows. The workflow is connected, not cobbled together.

How It Came Together

This wasn't designed in advance. It was extracted from the mistakes of a real project.

Building the macOS utility across five versions, I kept hitting the same wall. Version 1.2: built the DMG, missed the app icon, binary names collided on the case-insensitive filesystem – two bugs, two releases, 24 manual steps. Version 1.3: four features, one release, version string in six files, missed one, forgot the appcast signature, shipped broken. Version 1.4: the Sparkle framework wouldn't load because the binary was missing an @rpath entry. Three hours of debugging, then re-sign the DMG, re-build the appcast, re-upload the release, re-deploy the landing page.

That was the moment. Running the same ten commands for the third time that day – I stopped and built the slash command instead.

What Makes It Different

Most release automation assumes a team and a CI pipeline. Jenkins, GitHub Actions, YAML configuration. That's the right tool for the right context.

This is for one person with a terminal who wants to type /release 1.5.0 and be done.

The skills also read your actual codebase. They detect your project type – Swift, Node, Rust, Python, Ruby, Go – and use the right build and test commands. They generate content from what's actually in your README and help output, not from templates full of TODO: fill this in.

And they're honest about what they don't know. No build script? /release asks you for the command. No Sparkle? It skips signing. No Cloudflare? It skips deployment. Graceful on missing optional config.

The Compound Effect

Every time I solved a hard bug, I ran /ce:compound. It created a solution doc in docs/solutions/ with the problem, root cause, fix, and prevention strategy.

Eight docs later, when I hit a related issue, Claude surfaced the relevant solution during the planning phase – before I'd even encountered the bug.

Each release cycle shorter than the last — v1.0 took 3 hours, v1.4 took 3 minutes, as the docs/solutions library grew

The first time you solve "Sparkle framework missing @rpath in SPM-built binaries" takes three hours. Document it, and the next time takes three minutes. That's not a coincidence. It's the design.

This is why there are five phases, not four. Compound is what makes each cycle shorter than the last.

Try It

The release skills are open source, separate from the Compound Engineering plugin. You'll want both:

# The release, announce, landing-page, and contribute skills
git clone https://github.com/cc4-marketing/cc4-opensource.git
mkdir -p ~/.claude/skills
ln -s $(pwd)/cc4-opensource/skills/release ~/.claude/skills/release
ln -s $(pwd)/cc4-opensource/skills/announce ~/.claude/skills/announce
ln -s $(pwd)/cc4-opensource/skills/contribute ~/.claude/skills/contribute
ln -s $(pwd)/cc4-opensource/skills/landing-page ~/.claude/skills/landing-page

# The planning and building skills (Compound Engineering plugin)
# Install from: https://github.com/EveryInc/every-marketplace

The docs cover the full setup. The example walkthrough shows the entire lifecycle on a new project.

What's Next

I'm using this workflow on every project now. The muscle memory is building: brainstorm, plan, build, ship, announce, compound. Repeat.

The skills need refinement – edge cases I haven't hit, project types I haven't tested. If something breaks, that's a /ce:compound moment. Document it. Send a PR.

Each solution you add makes the next release a little more reliable. That's the whole point.

cc4.marketing – Claude Code for marketers who ship.

Get more like this

Subscribe to the CC4.Marketing newsletter for updates, guides, and practical AI marketing tips.

Subscribe on Substack