Building a Write-Once Publishing Pipeline

Published: (December 25, 2025 at 08:08 AM EST)
3 min read
Source: Dev.to

Source: Dev.to

The problem

Writing content is the easy part.

Publishing it consistently across platforms — with the right metadata, images, tags, canonical URLs, and updates — is where things usually fall apart.

Most workflows still look like this:

  • Write content in one tool
  • Copy/paste it into WordPress
  • Reformat it for another platform
  • Forget what was published where
  • Lose track of updates and fixes

I wanted something different:

Write once. Publish many. Update safely. Automate everything.

That goal led to building a fully automated, Git‑driven publishing pipeline.

The core idea

At the heart of this system is a simple principle:

Markdown in Git is the single source of truth.

Everything else — publishing, updating, tracking, media handling — is derived from that.

The pipeline is designed to be:

  • Idempotent (safe to run repeatedly)
  • Stateless at the CI level
  • State‑aware via a database
  • Extensible to new platforms
  • Ready for containerization and Kubernetes

Current feature set

Content & metadata

  • Markdown with YAML frontmatter
  • Title, slug, tags, featured image
  • Per‑platform publish switches
  • Optional force_update flag

Publishing

  • WordPress publishing via REST API (automatic post creation and updates)
  • Draft or published status
  • Automatic canonical URL generation
  • Uploads media via WordPress REST API
  • Reuses existing media (idempotent)
  • Declares images directly in Markdown

State tracking

  • PostgreSQL‑backed state tracking:
    • Which platform a post was published to
    • Platform‑specific post IDs
    • Content hashes
    • Publication timestamps
    • Automatic detection of content changes

Safe updates

  • Content hash comparison
  • Automatic post updates when Markdown changes
  • No duplicate publishing
  • No manual DB editing required

The workflow

  1. Write or edit a Markdown file
  2. Commit and push to Git
  3. Jenkins pipeline runs

The publisher:

  • Parses frontmatter
  • Computes content hash
  • Checks platform state in PostgreSQL
  • Uploads featured image if needed
  • Creates or updates the WordPress post
  • Updates state in the database

The pipeline finishes — safely and repeatably.

Flow diagram

High‑level publishing flow

Why this architecture works

Git is truth

All content and intent live in Git. No hidden state, no UI‑only changes.

Database is state

The database tracks what happened, not what should happen. This makes updates and corrections safe.

CI is stateless

Jenkins doesn’t store anything between runs, making the system portable and container‑friendly.

Platform abstraction

WordPress is just one publisher. Adding Dev.to, Substack, Patreon, or other targets requires no core changes.

Where this is heading

The pipeline already behaves like a backend service. Natural next steps:

  • Add more publishing targets (Dev.to, Substack, etc.)
  • Introduce analytics and engagement tracking
  • Package the publisher as a container
  • Run it inside Kubernetes
  • Add a simple UI on top

Offer it as Publishing as a Service: one repo, one workflow, one source of truth — for years of content.

Final thoughts

What started as “I just want to publish more easily” turned into a fully automated publishing platform with:

  • Git‑based content management
  • CI‑driven execution
  • Database‑backed state
  • Idempotent, update‑safe publishing

The best part? Writing content is now the only manual step left. Everything else is automation.

Back to Blog

Related posts

Read more »

What I Did This Week

Release of SlideNote Yesterday I released SlideNote, a Chrome browser side‑panel note‑taking extension. The idea came to me on Wednesday morning after growing...

Linus Torvalds is 'Vibe Coding'.

Well, the debate is officially over. Linus Torvalds, the creator of Linux and Git—arguably the most critical engineer of the modern internet—just dropped this b...