feat: blog auto-publish cron#33
Merged
Merged
Conversation
Adds a daily 06:00 UTC GitHub Actions workflow that:
- Scans content/blog/ for draft posts and categorizes them as
ready / scheduled / held based on the date + hold frontmatter
fields. The scan rule is:
draft = true AND date <= today AND NOT hold → ready
draft = true AND date > today → scheduled
hold = true → held (parked)
- For each ready post: opens a per-post squash-merge PR labelled
`autopublish` that flips draft to false. Each publish becomes its
own commit on main and triggers the existing deploy workflow.
- Always posts a status report to a pinned issue (label
`autopublish-status`) using a hidden bot-marker comment that gets
replaced in place each run, mirroring the rivet-delta pattern.
- Opens a separate `autopublish-failure` issue if any step fails.
Includes a workflow_dispatch trigger so the first run on 2026-04-29
can be fired manually rather than waiting for the schedule.
The scanner script is regex-based (not full-TOML) and handles only
the four frontmatter fields the cron cares about — title, date,
draft, hold — to avoid a tomllib dependency on the runner.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Daily 06:00 UTC GitHub Actions workflow that scans
content/blog/drafts and publishes those whose scheduled date has arrived. Pattern modelled on rivet-delta — bot-marker comment that updates in place, status report every run (not just on publish days).The convention this enforces:
What runs each day:
scripts/blog-autopublish.py --mode scan→ JSON inventorycron/publish-<slug>-<YYYY-MM-DD>, flipdraft = false, commit, push, open auto-merge PR (labelautopublish), squash-mergeautopublish-status) using<!-- blog-cron-status -->as the bot-markerautopublish-failureFiles:
.github/workflows/blog-autopublish.yml— the workflowscripts/blog-autopublish.py— scanner / flip / report (~150 lines, regex-based frontmatter parser, no extra deps)Sample report output
Tested locally simulating 2026-04-29 with the current draft inventory:
Test plan
workflow_dispatchmanually to verify the no-op path works (no publishes today, status issue gets created with the inventory)overdoing-the-verification-chainpublishes, deploy followsSecurity note
Triggers are
scheduleandworkflow_dispatchonly — nopull_request_targetor other event with untrusted user input. All values flowing into shellrun:blocks come from server-controlled context vars or from the scanner reading our own repo's frontmatter. No command-injection surface from external actors.🤖 Generated with Claude Code