mirror of
https://github.com/Studio-Saelix/sencho.git
synced 2026-08-10 10:49:35 +00:00
b5acfd8f58
* feat(scaffold): fully automate release blog post publishing Eliminates the manual PR-review step from the release blog scaffold pipeline. The workflow now commits the generated post directly to sencho-website main. scaffold-release-post.mjs changes: - Remove renderPrBody and all body_file handling - Update findLastAnchor to accept any post with a version: field, not just category: release posts. This allows narrative retrospectives to anchor the 5-release window. - Add buildHeadline: generates a post title from the top two added items and the total item count, e.g. "Sencho v0.69: Custom OIDC provider, Trivy scanning, and 12 more" - Add buildDescription: auto-generates a ~160-char SEO description from the version range and top three added items - Add calcReadingTime: estimates reading time from changelog word count - Add coveredVersionsProse: formats "v0.65.0 through v0.69.0" - Add updateMeta: inserts the new post into src/data/blog/meta.ts for Worker-side SEO meta injection - Remove the tmpdir/os import (no longer needed) release-blog-template.tsx.tmpl changes: - Replace all TODO placeholders with template variables (__TITLE__, __DESCRIPTION__, __READING_TIME__, __COVERED_VERSIONS_PROSE__) - Remove the screenshot placeholder section (auto-generated posts have no screenshot; the intro links to docs.sencho.io instead) release-blog-scaffold.yml changes: - Remove permission-pull-requests: write from app token (no PR created) - Replace "Commit and open draft PR" step with a simple git commit + push to sencho-website main. No duplicate-check step needed. - Include src/data/blog/meta.ts in the git add so the Worker SEO mapping stays in sync automatically. * fix(ci): use escapeTsxString in updateMeta to handle backslashes in blog post title and description CodeQL flagged two high-severity alerts: title and description written into meta.ts via updateMeta were only single-quote-escaped, leaving raw backslashes unescaped. A value containing a backslash followed by a special character would produce a malformed escape sequence in the generated TypeScript source. The escapeTsxString helper already handles both cases; use it consistently instead of an open-coded replace.
98 lines
3.2 KiB
YAML
98 lines
3.2 KiB
YAML
name: Release Blog Scaffold
|
|
|
|
# Fires on every v* tag push. Computes whether this tag completes the next
|
|
# every-5th-release window (source of truth = the latest post with a version:
|
|
# field in the sencho-website repo). If yes, generates a complete, TODO-free
|
|
# blog post and commits it directly to sencho-website main. No PR is opened.
|
|
on:
|
|
push:
|
|
tags:
|
|
- 'v*'
|
|
workflow_dispatch:
|
|
inputs:
|
|
tag:
|
|
description: 'Tag to scaffold against (e.g. v0.58.0). Must already exist.'
|
|
required: true
|
|
type: string
|
|
|
|
permissions:
|
|
contents: read
|
|
|
|
jobs:
|
|
scaffold:
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 10
|
|
steps:
|
|
# Same App-token pattern as release-please.yml. The app's installation
|
|
# must include both Sencho and sencho-website for the push + PR to work.
|
|
- name: Generate GitHub App installation token
|
|
id: app-token
|
|
uses: actions/create-github-app-token@1b10c78c7865c340bc4f6099eb2f838309f1e8c3 # v3.1.1
|
|
with:
|
|
app-id: ${{ secrets.APP_ID }}
|
|
private-key: ${{ secrets.APP_PRIVATE_KEY }}
|
|
owner: ${{ github.repository_owner }}
|
|
repositories: |
|
|
Sencho
|
|
sencho-website
|
|
permission-contents: write
|
|
|
|
- name: Resolve target tag
|
|
id: target
|
|
run: |
|
|
set -euo pipefail
|
|
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
|
|
tag="${{ inputs.tag }}"
|
|
else
|
|
tag="${GITHUB_REF_NAME}"
|
|
fi
|
|
echo "tag=${tag}" >> "$GITHUB_OUTPUT"
|
|
echo "Resolved target tag: ${tag}"
|
|
|
|
- name: Check out Sencho (full history for tags)
|
|
uses: actions/checkout@v6
|
|
with:
|
|
fetch-depth: 0
|
|
fetch-tags: true
|
|
|
|
- name: Check out sencho-website
|
|
uses: actions/checkout@v6
|
|
with:
|
|
repository: ${{ github.repository_owner }}/sencho-website
|
|
token: ${{ steps.app-token.outputs.token }}
|
|
path: website-repo
|
|
fetch-depth: 1
|
|
|
|
- name: Setup Node
|
|
uses: actions/setup-node@v6
|
|
with:
|
|
node-version: '20'
|
|
|
|
- name: Run scaffold script
|
|
id: scaffold
|
|
run: |
|
|
set -euo pipefail
|
|
node .github/scripts/scaffold-release-post.mjs \
|
|
--tag "${{ steps.target.outputs.tag }}" \
|
|
--changelog CHANGELOG.md \
|
|
--website website-repo
|
|
|
|
- name: Commit and push release post to sencho-website
|
|
if: steps.scaffold.outputs.scaffold == 'true'
|
|
env:
|
|
TAG: ${{ steps.target.outputs.tag }}
|
|
POST_PATH: ${{ steps.scaffold.outputs.post_path }}
|
|
run: |
|
|
set -euo pipefail
|
|
cd website-repo
|
|
git config user.name "sencho-release-bot[bot]"
|
|
git config user.email "sencho-release-bot[bot]@users.noreply.github.com"
|
|
git add "${POST_PATH}" src/data/blog/index.ts src/data/blog/meta.ts
|
|
git commit -m "chore(blog): auto-publish release post for ${TAG}"
|
|
git push origin main
|
|
|
|
- name: Report skip
|
|
if: steps.scaffold.outputs.scaffold != 'true'
|
|
run: |
|
|
echo "No scaffold this run. Window did not reach the next every-5th-release anchor."
|