I built a CLI Tool to Automate Astro Blog Posting

astro automation github actions cli

Astro Logo

Meta-alert: This post was created and managed using the tool it describes.

The Ironic Beginning

I was working on this blog when the idea for Blogue hit me. I had just spent ten minutes manually creating a markdown file, copying frontmatter from another post, and double-checking my Zod schema to make sure I got the field names right. Again.

The irony wasn’t lost on me when I realized I’d eventually write about this experience in a blog post that would require… the exact same tedious process.

So I built the tool first, then used it to create this post.

The Actual Problem

Here’s what my blog post creation looked like before:

  1. Open my Astro project
  2. Navigate to src/content/blog/
  3. Create a new .md file with a URL-friendly name
  4. Copy frontmatter from an existing post
  5. Check src/content/config.ts to remember which fields are required
  6. Update the date, title, tags, description
  7. Set draft: true
  8. Start writing

When ready to publish:

  1. Change draft: true to draft: false
  2. Create a new git branch
  3. Commit the changes
  4. Push and create a PR
  5. Wait for Vercel to build
  6. Merge the PR
  7. Clean up the branch

This process took longer than writing short posts.

The Tool That Emerged

Blogue automates everything except the actual writing. It reads your Astro content configuration and generates posts that match your schema exactly.

# What I do now:
blogue new
# (Interactive prompts for title, description, tags)

blogue publish --auto-push
# (Handles the entire GitHub workflow)

Technical Deep Dive

Reading Astro Configurations

The core insight was that Astro already defines your content structure. If you have this in src/content/config.ts:

const blog = defineCollection({
  type: 'content',
  schema: z.object({
    title: z.string(),
    description: z.string().optional(),
    pubDate: z.coerce.date(),
    updatedDate: z.coerce.date().optional(),
    heroImage: z.string().optional(),
    tags: z.array(z.string()).default([]),
  }),
});

Blogue parses this with Babel, extracts the Zod schema, and generates frontmatter that matches perfectly:

---
title: "Your Post Title"
description: "Optional description"
pubDate: 2024-07-22T00:00:00.000Z
tags: []
draft: true
---

Handling Multiple Collections

My blog has different content types (blog posts, project notes, tutorials), each with different schemas. Blogue detects all collections and lets you choose:

$ blogue new
? Which content collection? 
 blog (content) - 6 required fields
  notes (content) - 3 required fields  
  projects (content) - 8 required fields

The GitHub Workflow

The publishing automation handles what I used to do manually:

  1. Creates a branch named blogue/post-slug
  2. Commits with a descriptive message
  3. Pushes to GitHub
  4. Creates a PR with auto-generated title and description
  5. Monitors the CI status
  6. Auto-merges when Vercel build succeeds
  7. Cleans up the branch
  8. Returns you to the main branch

All from blogue publish --auto-push.

Beyond Astro

Not everyone uses Astro, so Blogue also works by learning from existing posts. It analyzes your markdown files, identifies common frontmatter patterns, and generates templates that match your style.

If 80% of your posts have a tags field, it’s marked as required. If only 20% have featured: true, it’s marked optional. The tool adapts to your conventions.

This Post’s Creation Story

I created this post using Blogue:

$ blogue new
? What's the title of your blog post? Building a Tool to Manage This Very Blog Post
? Brief description (optional): Meta-alert: This post was created using the tool it describes
? Which content collection? blog
✅ Blog post created successfully!
📄 File: src/content/blog/building-a-tool-to-manage-this-very-blog-post.md
💡 Run `blogue publish` when ready to publish

The generated frontmatter matched my schema exactly:

---
title: "Building a Tool to Manage This Very Blog Post"
description: "Meta-alert: This post was created using the tool it describes"
pubDate: 2024-07-22T10:30:00.000Z
tags: []
draft: true
---

No copying from other files, no schema checking, no manual date formatting.

What I Learned Building This

Developer Tools Should Solve Real Problems

I built Blogue because I was genuinely frustrated with my workflow. The best tools come from scratching your own itch.

Automation Should Feel Invisible

Good automation doesn’t feel like automation. It feels like the computer finally understanding what you want to do.

Configuration Over Convention

Rather than imposing a structure, Blogue reads your existing setup and works within it. Your content schema, your naming conventions, your workflow.

Where It’s Going

More Frameworks: Next.js, Gatsby, Nuxt content systems Editor Integration: VS Code extension for in-editor management Content Enhancement: AI-powered tag suggestions, SEO hints Team Features: Multi-author workflows, editorial calendars

Try It On Your Blog

npm install -g @blogue/cli
cd your-blog-project
blogue new

If you’re using Astro, it should work immediately. Other frameworks fall back to pattern detection.

The source is at github.com/iabrmv/blogue.

Meta-Conclusion

I’m publishing this post using blogue publish --auto-push. It will create a PR, wait for my Astro build to pass, auto-merge, and clean up the branch.

By the time you read this, the tool will have managed its own announcement. There’s something satisfying about that.