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 release post's # `version` field in the sencho-website repo). If yes, opens a DRAFT PR in # sencho-website containing a pre-filled blog post scaffold; a human writes # the narrative, adds the screenshot, and marks the PR ready. 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 permission-pull-requests: 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 open draft PR in sencho-website if: steps.scaffold.outputs.scaffold == 'true' env: GH_TOKEN: ${{ steps.app-token.outputs.token }} TAG: ${{ steps.target.outputs.tag }} BRANCH: ${{ steps.scaffold.outputs.branch }} POST_PATH: ${{ steps.scaffold.outputs.post_path }} BODY_FILE: ${{ steps.scaffold.outputs.body_file }} OWNER: ${{ github.repository_owner }} run: | set -euo pipefail cd website-repo # Short-circuit if a scaffold PR for this branch already exists (e.g., # a manual workflow_dispatch retry against the same tag). existing=$(gh pr list \ --repo "${OWNER}/sencho-website" \ --head "${BRANCH}" \ --state open \ --json number --jq '.[0].number // empty') if [ -n "${existing}" ]; then echo "PR already exists for ${BRANCH} (#${existing}); nothing to do." exit 0 fi git config user.name "sencho-release-bot[bot]" git config user.email "sencho-release-bot[bot]@users.noreply.github.com" git checkout -B "${BRANCH}" git add "${POST_PATH}" src/data/blog/index.ts git commit -m "chore: scaffold release post for ${TAG}" git push -u origin "${BRANCH}" --force-with-lease gh pr create \ --repo "${OWNER}/sencho-website" \ --base main \ --head "${BRANCH}" \ --title "chore: scaffold release post for ${TAG}" \ --body-file "${BODY_FILE}" \ --draft - 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."