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
124 lines
5.3 KiB
YAML
124 lines
5.3 KiB
YAML
name: cut-release
|
|
# Every Tuesday 09:00 Asia/Shanghai, cut the next minor release branch from main HEAD:
|
|
# 1. Compute version (highest release/vX.Y.Z -> bump minor -> X.(Y+1).0; e.g. 0.11.0 -> 0.12.0)
|
|
# 2. Create release/vX.Y.Z, bump apps/packaged/package.json, push
|
|
# 3. Create the "backport release/vX.Y.Z" label
|
|
# The push uses the App token (not GITHUB_TOKEN), so it triggers notify-release-feishu
|
|
# -> builds a nightly package and posts the Feishu card.
|
|
|
|
on:
|
|
schedule:
|
|
- cron: '0 1 * * 2' # 01:00 UTC = 09:00 Asia/Shanghai, Tuesday
|
|
workflow_dispatch:
|
|
inputs:
|
|
version:
|
|
description: 'Full version x.y.z (empty = bump minor of the highest release branch)'
|
|
required: false
|
|
default: ''
|
|
|
|
permissions:
|
|
contents: read # actual writes go through the App token below
|
|
|
|
jobs:
|
|
cut:
|
|
if: github.repository == 'nexu-io/open-design'
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/create-github-app-token@v2
|
|
id: app
|
|
with:
|
|
app-id: ${{ secrets.RELEASE_BOT_APP_ID }}
|
|
private-key: ${{ secrets.RELEASE_BOT_PRIVATE_KEY }}
|
|
|
|
- uses: actions/checkout@v4
|
|
with:
|
|
ref: main # always cut from main HEAD, even on a manual dispatch from another branch
|
|
fetch-depth: 0
|
|
token: ${{ steps.app.outputs.token }}
|
|
|
|
- uses: actions/setup-node@v4
|
|
with:
|
|
node-version: 24
|
|
|
|
- name: Compute next version
|
|
id: ver
|
|
env:
|
|
# Never interpolate the raw input into the shell; pass via env and validate.
|
|
INPUT_VERSION: ${{ inputs.version }}
|
|
run: |
|
|
set -euo pipefail
|
|
if [ -n "$INPUT_VERSION" ]; then
|
|
# Strict x.y.z, digits only — rejects shell metacharacters, newlines, etc.
|
|
if ! printf '%s' "$INPUT_VERSION" | grep -Eq '^[0-9]+\.[0-9]+\.[0-9]+$'; then
|
|
echo "::error::Invalid version '$INPUT_VERSION' (expected x.y.z, digits only)"
|
|
exit 1
|
|
fi
|
|
V="$INPUT_VERSION"
|
|
else
|
|
latest=$(git ls-remote --heads origin 'release/v*' \
|
|
| sed -E 's#.*/release/v##' \
|
|
| grep -E '^[0-9]+\.[0-9]+\.[0-9]+$' \
|
|
| sort -t. -k1,1n -k2,2n -k3,3n | tail -1)
|
|
major=${latest%%.*}; rest=${latest#*.}; minor=${rest%%.*}
|
|
V="${major}.$((minor+1)).0"
|
|
fi
|
|
# V is now guaranteed to match ^[0-9]+\.[0-9]+\.[0-9]+$
|
|
echo "version=$V" >> "$GITHUB_OUTPUT"
|
|
echo "branch=release/v$V" >> "$GITHUB_OUTPUT"
|
|
echo "Cutting v$V (branch release/v$V)"
|
|
|
|
- name: Bail out if the branch already exists
|
|
env:
|
|
BRANCH: ${{ steps.ver.outputs.branch }}
|
|
run: |
|
|
set -euo pipefail
|
|
if git ls-remote --exit-code --heads origin "$BRANCH" >/dev/null 2>&1; then
|
|
echo "::error::$BRANCH already exists, skipping"
|
|
exit 1
|
|
fi
|
|
|
|
- name: Create branch + bump version + push
|
|
env:
|
|
VERSION: ${{ steps.ver.outputs.version }}
|
|
BRANCH: ${{ steps.ver.outputs.branch }}
|
|
run: |
|
|
set -euo pipefail
|
|
git config user.name 'open-design-release-bot[bot]'
|
|
git config user.email 'open-design-release-bot[bot]@users.noreply.github.com'
|
|
git switch -c "$BRANCH"
|
|
( cd apps/packaged && npm pkg set version="$VERSION" )
|
|
git commit -am "chore(release): v$VERSION"
|
|
git push origin "$BRANCH" # App token push -> triggers notify-release-feishu (nightly + Feishu)
|
|
|
|
- name: Create backport label
|
|
env:
|
|
GH_TOKEN: ${{ steps.app.outputs.token }}
|
|
VERSION: ${{ steps.ver.outputs.version }}
|
|
run: |
|
|
set -euo pipefail
|
|
gh label create "backport release/v$VERSION" \
|
|
--repo nexu-io/open-design \
|
|
--color 0E8A16 \
|
|
--description "Backport this fix to release/v$VERSION" \
|
|
--force
|
|
|
|
# Post an immediate "branch cut" card so the team is notified the moment the
|
|
# release branch exists, without waiting ~20-40 min for notify-release-feishu
|
|
# to finish the prerelease build. The download card still follows from that
|
|
# build. feishu-notice.ts only imports node:crypto, so the setup-node above
|
|
# is all it needs.
|
|
- name: Notify Feishu that the branch was cut
|
|
env:
|
|
FEISHU_WEBHOOK: ${{ secrets.FEISHU_RELEASE_WEBHOOK }}
|
|
FEISHU_SIGN_SECRET: ${{ secrets.FEISHU_RELEASE_SIGN_SECRET }}
|
|
NOTICE_TITLE: "🌿 已切出 release 分支 v${{ steps.ver.outputs.version }}(大版本 minor)"
|
|
NOTICE_TEMPLATE: "green"
|
|
NOTICE_BODY: |
|
|
**分支**:[`release/v${{ steps.ver.outputs.version }}`](${{ github.server_url }}/${{ github.repository }}/tree/release/v${{ steps.ver.outputs.version }})(从 main 切出,大版本 / minor)
|
|
|
|
**Backport label**:`backport release/v${{ steps.ver.outputs.version }}` —— 要回灌到这个版本的修复,给 PR 打这个 label。
|
|
|
|
Prerelease 打包已开始(约 20–40 分钟);完成后会再发一张带各平台下载链接的卡片。
|
|
RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
|
|
run: node --experimental-strip-types tools/release/src/notifications/feishu-notice.ts
|