+
+ TODO: write a short narrative introduction that highlights the most
+ user-visible change across versions __COVERED_VERSIONS__. Link the
+ relevant docs section at{' '}
+ https://docs.sencho.io.
+
+
+ Highlight
+
+ TODO: embed at least one screenshot of the headline feature.
+
+
+
+ What's in this release
+__ADDED_BLOCK__
+__FIXED_BLOCK__
+__CHANGED_BLOCK__
+
+ ),
+}
diff --git a/.github/scripts/scaffold-release-post.mjs b/.github/scripts/scaffold-release-post.mjs
new file mode 100644
index 00000000..33b50433
--- /dev/null
+++ b/.github/scripts/scaffold-release-post.mjs
@@ -0,0 +1,323 @@
+#!/usr/bin/env node
+// Scaffolds a release blog post in the Sencho website repo when the tag that
+// triggered this run completes a run of 5 releases since the last post's anchor.
+// Invoked by .github/workflows/release-blog-scaffold.yml. See website/CLAUDE.md
+// for the cadence rules this script enforces.
+
+import { execFileSync } from 'node:child_process'
+import { readFileSync, writeFileSync, readdirSync, existsSync } from 'node:fs'
+import { tmpdir } from 'node:os'
+import { join, dirname } from 'node:path'
+import { fileURLToPath } from 'node:url'
+
+const HERE = dirname(fileURLToPath(import.meta.url))
+const REPO_ROOT = join(HERE, '..', '..')
+const TEMPLATE_PATH = join(REPO_ROOT, '.github', 'release-blog-template.tsx.tmpl')
+
+const WINDOW_SIZE = 5
+// Section names come from release-please-config.json's changelog-sections.
+// Security gets its own bucket so hardening items do not get lost.
+const SECTION_MAP = {
+ Added: 'added',
+ Fixed: 'fixed',
+ Changed: 'changed',
+ Security: 'fixed',
+}
+
+function parseArgs(argv) {
+ const args = { dryRun: false }
+ for (let i = 0; i < argv.length; i++) {
+ const a = argv[i]
+ if (a === '--dry-run') args.dryRun = true
+ else if (a === '--tag') args.tag = argv[++i]
+ else if (a === '--changelog') args.changelog = argv[++i]
+ else if (a === '--website') args.website = argv[++i]
+ }
+ if (!args.tag || !args.changelog || !args.website) {
+ throw new Error('Usage: --tag vX.Y.Z --changelog