Skip to content

Add blog post creator script - #71

Draft
scriptautomate-bc wants to merge 3 commits into
mainfrom
topic/blog-post-templates
Draft

scriptautomate-bc wants to merge 3 commits into
mainfrom
topic/blog-post-templates

Conversation

@scriptautomate-bc

@scriptautomate-bc scriptautomate-bc commented Jul 13, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Adds scripts/new-blog-post.py, a generator for the site's most repetitive blog post types — GA/bugfix releases, release candidates, and security/CVE advisories — plus the supporting config it depends on (scripts/releases.toml, scripts/release-log.toml, scripts/tags.toml validation via scripts/validate-tags.py).

Rather than embedding each post type's body copy as Python string literals, all body content lives in plain Markdown files under scripts/blog-templates/, each with a small number of $placeholder variables (e.g. $version, $major, $track). These are ordinary, readable .md files — a human or an AI can open one directly and write a post by hand from it, with or without this tooling, and editing a template's wording changes every future post of that type without touching Python.

Every template was checked against the actual latest published posts of each type (not just written from memory) and revised to match current house style exactly — see Verification.

What changed

  • scripts/new-blog-post.py — generates release, rc, security, and announcement posts. Handles file naming/front matter conventions, --publish vs. default draft: true, and same-day filename collisions.
  • scripts/blog-templates/ — one or more .md templates per post type:
    • release-ga-body.md / release-bugfix-body.md — single-version release, split by whether the version is an actual x.0 GA promotion.
    • release-multi-version-block.md — one block per version in a combined multi-version release post.
    • install-upgrade-notes-versioned.md, reporting-feedback.md — shared sections for single-version release posts.
    • installation-notes-simple.md, reporting-issues-simple.md — shared simplified sections for RC and multi-version posts.
    • rc-intro-block.md — release candidate body.
    • security-body.md, security-release-notes-block.md — security/CVE advisory body and its per-version release-notes block.
    • announcement-body.md — placeholder body for general announcement posts.
  • scripts/_blog_common.py — shared helpers: approved-tag/release-track/release-log loaders, and a new render_template() that loads a scripts/blog-templates/*.md file and fills in its $placeholders via stdlib string.Template (no new dependency).
  • scripts/releases.toml — per-major-version release track (LTS/STS/RC) lookup.
  • scripts/release-log.toml — log of every version ever announced, pre-populated from this repo's blog post history; used to reject duplicate or out-of-sequence version announcements.
  • README — documents the new-blog-post.py usage, the templates directory, and the release-log/releases-toml conventions.

Verification

Every template was diffed byte-for-byte against real published posts before being finalized, not just visually compared:

  • Single-version release (GA and bugfix) — verified against 3008.0 (true GA) and 3008.2 (bugfix): generated output is byte-identical modulo the version string.
  • Release candidate — the two most recent RC posts (rc3, rc4) use a different structure than the two before them (rc1, rc2); the template was rebuilt to match the current style and verified byte-identical against the real rc4 post.
  • Multi-version release block — no standalone multi-version-only post exists since that same style change, but rc3 (a combined bugfix+RC post) includes a bugfix block for 3006.25; the template was rebuilt to match and verified byte-identical against that block.
  • Security/CVE advisory — verified against the most recent genuine CVE-release post (2025-11-20); needed no changes. (The single most recent security-tagged post is a bespoke supply-chain-incident notice, not a repeatable template case, and was intentionally not modeled.)
  • Announcement — trivial placeholder body, unchanged from the original.
  • scripts/validate-tags.py still passes against all existing posts.
  • A correction made mid-review was itself re-verified against evidence: an earlier pass had split the release "Reporting Issues & Feedback" wording by GA-vs-bugfix status on editorial grounds, but checking all five real posts published since the current style was adopted (3008.0, 3008.1, 3008.2, 3006.26, 3006.27) showed all five use identical wording regardless of GA status. Reverted to match observed reality rather than editorial judgment.

Not in this PR

  • No new command for a combined "bugfix + RC in one post" type (the shape seen in rc3), since the ask here was to bring existing templates up to date, not add new post-composition features. The per-version block templates (release-multi-version-block.md, rc-intro-block.md) are already structured so that composing them into a single combined post later would be straightforward if that's ever wanted.

@scriptautomate-bc scriptautomate-bc self-assigned this Jul 13, 2026
@scriptautomate-bc
scriptautomate-bc force-pushed the topic/blog-post-templates branch from 8ae4c0f to ba5ff67 Compare August 21, 2026 10:40
Post bodies for release/rc/security/announcement used to be Python
f-strings and string constants embedded directly in
scripts/new-blog-post.py. Move them into scripts/blog-templates/ as
plain, readable Markdown files with $placeholder variables (e.g.
$version), loaded via a new _blog_common.render_template() helper
(stdlib string.Template, no new dependency).

This means a human or an AI can open one of these template files
directly and write a post by hand from it, with or without
new-blog-post.py, and editing a template's wording changes every
future post of that type without touching Python code.

Also fixes a real bug caught along the way: every single-version
release post -- an actual GA promotion or a routine bugfix alike --
got the same "thanks to our RC testers, this GA release" text. Only
an actual x.0 GA promotion should say that; split into
reporting-feedback-ga.md vs reporting-feedback-generic.md.

Verified byte-for-byte identical output against the pre-refactor
script across all 7 post-generation paths (single GA release, single
bugfix release, multi-version release, RC, single-version security,
multi-version security, announcement) using real version numbers
against the actual release-log.toml/releases.toml.
Reviewed the actual latest published posts of each type and found the
templates had drifted from real practice in two places:

- RC posts (rc1/rc2 matched the old template, but rc3/rc4 -- the two
  most recent -- consistently use a different structure: "excited to
  announce the release of **Salt $major RC$n**" intro, a "## Salt
  $major RC$n (Release Candidate)" block, simplified "Installation &
  Upgrade Notes"/"Reporting Issues" sections, and a different closing
  line. Replaced rc-body.md with rc-intro-block.md plus two new
  shared templates (installation-notes-simple.md,
  reporting-issues-simple.md) matching that.

- Multi-version release blocks: no standalone multi-version-only post
  exists since that same style transition, but rc3 (a combined
  bugfix+RC post) shows what a post-transition bugfix block looks
  like: "## Salt $version $track (Bugfix Release)" with a descriptive
  sentence and Install Guide/Release Notes/Changelog/Source bullets,
  wrapped in the same simplified shared footer as RC posts. Updated
  release-multi-version-block.md to match, verified byte-for-byte
  against rc3's actual 3006.25 block.

- Reverted the earlier GA-vs-bugfix reporting-feedback split from the
  previous commit: checked every real post since the style transition
  (3008.0, 3008.1, 3008.2, 3006.26, 3006.27) and all five -- GA and
  bugfix alike -- consistently use the "thanks to our RC testers/this
  GA release" wording. That split was based on my own editorial
  judgment, not on what's actually being published; reality wins.
  Single-version release templates otherwise needed no changes --
  they already matched every recent post byte-for-byte.

- Security/CVE post template needed no changes -- the latest genuine
  CVE-release post (2025-11-20) still matches it exactly. (The most
  recent security-tagged post, a supply-chain-incident notice, is a
  bespoke one-off narrative, not a repeatable template case.)

Verified every change byte-for-byte against real published posts
(3008.0, 3008.2, rc3's 3006.25 block, rc4) before committing.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant