070959e133
landing-page-staging / Deploy landing page to staging (push) Has been skipped
landing-page-ci / Validate landing page (push) Failing after 4s
visual-baseline / Capture visual baselines (push) Has been cancelled
bake-plugin-previews / Bake plugin previews (push) Has been cancelled
123 lines
5.8 KiB
YAML
123 lines
5.8 KiB
YAML
name: bake-plugin-previews-release
|
|
|
|
# Release-cut full bake (spec slice 3). On a push to a release/** branch, render
|
|
# every preview (hash-skip reuses unchanged), publish the immutable clips to R2,
|
|
# and commit the authoritative manifest snapshot onto the release branch. The
|
|
# manifest then flows to main via the normal non-squash release back-merge.
|
|
#
|
|
# Bumping BAKE_VERSION at release time is the explicit lever to refresh shared-
|
|
# input changes (fonts / web CSS / design systems / renderer) that per-file
|
|
# triggers cannot detect — a full sweep alone would reuse, not re-render, them.
|
|
|
|
on:
|
|
push:
|
|
branches: ['release/**']
|
|
paths-ignore:
|
|
- 'data/plugin-previews/**' # our own manifest commit must not re-trigger
|
|
workflow_dispatch: {}
|
|
|
|
permissions:
|
|
contents: write # commit the authoritative manifest onto the release branch
|
|
|
|
concurrency:
|
|
group: bake-plugin-previews-release-${{ github.ref }}
|
|
cancel-in-progress: false
|
|
|
|
jobs:
|
|
bake:
|
|
name: Bake plugin previews (release cut)
|
|
# `push` is already limited to release/**, but `workflow_dispatch` can be run
|
|
# from any ref. The commit step pushes the authoritative manifest to the
|
|
# triggering ref with contents:write, so a dispatch on `main` would write
|
|
# straight to main and bypass the release back-merge/review path. Hard-gate
|
|
# the whole job to release branches.
|
|
if: ${{ startsWith(github.ref, 'refs/heads/release/') }}
|
|
runs-on: ubuntu-24.04
|
|
timeout-minutes: 90
|
|
steps:
|
|
- name: Checkout
|
|
uses: actions/checkout@v6.0.2
|
|
with:
|
|
ref: ${{ github.ref }}
|
|
fetch-depth: 0
|
|
# Read-only clone with the default token, but do NOT persist it as a
|
|
# github.com credential. release/** is guarded by the "Protected
|
|
# branches (preview/*, release/v*)" ruleset (deletion / non_fast_forward
|
|
# / pull_request), so a direct push is rejected (GH013) unless the pusher
|
|
# is a bypass actor. github-actions[bot] is NOT one — so the manifest
|
|
# writeback below force-authenticates as open-design-bot, which IS a
|
|
# bypass actor, via an explicit token URL. A persisted github.token
|
|
# extraheader would override that inline token on push (see #5357), so
|
|
# drop it; nothing between here and the push needs the persisted cred.
|
|
persist-credentials: false
|
|
|
|
- name: Loop guard — skip the bake bot's own manifest commit
|
|
id: guard
|
|
# Belt-and-suspenders with paths-ignore above: also skip when the head
|
|
# commit was authored by the bake bot, so the manifest writeback cannot
|
|
# re-trigger this workflow.
|
|
run: |
|
|
AUTHOR="$(git log -1 --format='%ae')"
|
|
echo "head commit author: $AUTHOR"
|
|
if [ "$AUTHOR" = "bot@open-design.ai" ]; then
|
|
echo "skip=true" >> "$GITHUB_OUTPUT"
|
|
echo "head commit is the bake bot's manifest commit — skipping to break the loop"
|
|
else
|
|
echo "skip=false" >> "$GITHUB_OUTPUT"
|
|
fi
|
|
|
|
- name: Setup workspace
|
|
if: ${{ steps.guard.outputs.skip != 'true' }}
|
|
uses: ./.github/actions/setup-workspace
|
|
|
|
- name: Render previews + publish clips to R2
|
|
if: ${{ steps.guard.outputs.skip != 'true' }}
|
|
uses: ./.github/actions/bake-previews
|
|
with:
|
|
upload: 'true'
|
|
r2-access-key-id: ${{ secrets.CLOUDFLARE_R2_REPOSITORY_ASSETS_AK }}
|
|
r2-secret-access-key: ${{ secrets.CLOUDFLARE_R2_REPOSITORY_ASSETS_SK }}
|
|
r2-bucket: ${{ secrets.CLOUDFLARE_R2_REPOSITORY_ASSETS_BUCKET }}
|
|
r2-endpoint: ${{ secrets.CLOUDFLARE_R2_REPOSITORY_ASSETS_URL }}
|
|
|
|
- name: Mint the open-design-bot token for the release-branch push
|
|
if: ${{ steps.guard.outputs.skip != 'true' }}
|
|
id: bot
|
|
# open-design-bot (app id 3640364) is a bypass actor on the
|
|
# "Protected branches (preview/*, release/v*)" ruleset, so its push clears
|
|
# the pull_request rule that rejects github-actions[bot] (GH013). The
|
|
# release bake pushes the manifest directly (it then rides the non-squash
|
|
# release back-merge to main). Minted here — after the long render, not at
|
|
# job start — because an App token lives ~1h and the render can run long.
|
|
uses: actions/create-github-app-token@v3.2.0
|
|
with:
|
|
client-id: ${{ secrets.BOT_APP_CLIENT_ID }}
|
|
private-key: ${{ secrets.BOT_APP_PRIVATE_KEY }}
|
|
owner: nexu-io
|
|
repositories: open-design
|
|
|
|
- name: Commit the authoritative manifest onto the release branch
|
|
if: ${{ steps.guard.outputs.skip != 'true' }}
|
|
env:
|
|
BOT_TOKEN: ${{ steps.bot.outputs.token }}
|
|
run: |
|
|
OLD=data/plugin-previews/manifest.json
|
|
NEW=.tmp/plugin-previews/manifest.json
|
|
# Capture on its own line so `set -e` surfaces a helper error (exit 2)
|
|
# rather than command substitution swallowing it into the test.
|
|
diff_result="$(node scripts/plugin-previews-diff.mjs "$OLD" "$NEW")"
|
|
case "$diff_result" in
|
|
changed) ;;
|
|
unchanged) echo "previews unchanged — nothing to commit"; exit 0 ;;
|
|
*) echo "unexpected diff result: '$diff_result'" >&2; exit 1 ;;
|
|
esac
|
|
cp "$NEW" "$OLD"
|
|
git config user.name "open-design-bot"
|
|
git config user.email "bot@open-design.ai"
|
|
git add "$OLD"
|
|
git commit -m "chore(plugin-previews): refresh baked preview manifest (release cut)"
|
|
# Push as open-design-bot (a ruleset bypass actor) via an explicit token
|
|
# URL. A plain `git push origin` would authenticate as github-actions[bot]
|
|
# and be rejected by the release/** pull_request rule (GH013).
|
|
git push "https://x-access-token:${BOT_TOKEN}@github.com/${GITHUB_REPOSITORY}.git" "HEAD:${GITHUB_REF#refs/heads/}"
|