Skip to content

Behind the scenes

How we publish every day without a CMS

getReport now ships one new guide or post every day for the next six months. There is no CMS behind it: markdown files, pull requests and one scheduled rebuild.

getReport team4 min read

From this week, getReport publishes one new piece of content every day: a guide, a comparison measured with our own tools, or a post like this one. The whole publishing system is markdown files in a git repository, a date check at build time, and one scheduled job. This post explains how it works, because the same setup fits any static or server-rendered site that would rather not run a CMS.

Why not a CMS

Every page on getreport.app is rendered ahead of time and shipped as part of one deployable image. That has real advantages: the whole site is reviewed in pull requests, every change runs the full test suite (broken internal links fail the build, charts without a source line fail the build), and the server does nothing at request time that could break at 3 a.m.

It has one apparent disadvantage: nothing can appear on a schedule, because nothing changes between deploys. We also can't cheat with incremental regeneration; our content security policy is built from hashes of exactly what the build produced, and a check in the build refuses pages that want to re-render themselves later. A scheduled post therefore can't be a runtime feature. It has to be a build-time one.

Flow of the daily publish: writers merge future-dated markdown days ahead; at 05:40 UTC a scheduled job checks what is due, rebuilds the site with today's date, deploys it, and submits the new URLs to IndexNow
One merged batch covers a week or more; the daily job only makes due pieces visible.

How a piece gets published on a Tuesday

  1. It is written days earlier, as a markdown file with a date in its front matter: published: 2026-10-07. Guides and posts are produced in weekly batches, reviewed and merged like any code change.
  2. The site hides future dates. The loaders that feed the pages, the sitemaps and the RSS feeds drop anything dated after "today". A merged-but-future piece is in the repository, but it renders nowhere: no index entry, no sitemap line, no feed item, no page.
  3. "Today" is pinned at build time. The build takes the current UTC date as an input, and that date is part of the fingerprint that decides whether the site image needs rebuilding. The first build of each day is therefore always a real build; a second deploy the same day reuses it.
  4. A scheduled job is the clock. At 05:40 UTC a small workflow reads the front matter of every piece of content. If something is due today, it triggers the normal deploy; same build, same tests, same rollout as any merge. If nothing is due, it does nothing. It also counts how many consecutive future days already have content merged, and complains loudly when the buffer drops under 7 days.
  5. Search engines are told, not left to guess. After the rollout, the day's new URLs are submitted to IndexNow, and the sitemaps' last-modified dates update by themselves because they come from the same date-aware loaders.
  • 347guides live before the daily cadence started
  • 182days of content planned and researched ahead
  • 1scheduled job added to make it all publish

What this buys us

Honest dates. The date on a page is the date the build made it public, not a value someone typed into an admin panel. The RSS feed, the sitemap and the page all agree because they all read the same front matter through the same date filter.

Review before publish, always. A scheduled piece is merged days before it goes out, which means it passed the link checker, the accessibility tests and a human review while there was still time to fix it. There is no "publish now" button to press at midnight and no draft state living only in a database.

Nothing new to operate. No CMS to update, no editorial database to back up, no webhooks. The one moving part is a scheduled workflow that runs a small script and, most days, exits after printing "nothing due today".

What it costs

A piece goes live at the morning rebuild, not at midnight: fine for guides, wrong for breaking news. Updating an already-published page can't be scheduled the same way, because there is only one copy of the file; edits go live when they merge. And the whole thing depends on discipline: if nobody merges next week's batch, the daily job has nothing to publish; which is exactly what the buffer warning is for.

If you want to see what the daily cadence produces, the guides index sorts by date, and the blog feed carries every post. Day one of the calendar was yesterday's guide on AI visibility; tomorrow is about a status code you have definitely met.

How does your site compare?

Free report, no account, ready in under a minute.

Check my site

More posts

All posts →
Product

Check your site on every deploy

The getReport GitHub Action fails your build when a score drops. The story behind it, the design decisions, and a workflow you can paste in today.

9 min read