Skip to content

test(spec): 修掉 flow fixture 教的三种跑不通的形状 (#4924) #9354

test(spec): 修掉 flow fixture 教的三种跑不通的形状 (#4924)

test(spec): 修掉 flow fixture 教的三种跑不通的形状 (#4924) #9354

Workflow file for this run

name: PR Automation
on:
pull_request:
types: [opened, synchronize, reopened, labeled, unlabeled]
jobs:
pr-size:
name: Check PR Size
runs-on: ubuntu-latest
permissions:
pull-requests: write
steps:
- name: Add size label
uses: codelytv/pr-size-labeler@v1.10.4
with:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
xs_label: 'size/xs'
xs_max_size: '10'
s_label: 'size/s'
s_max_size: '100'
m_label: 'size/m'
m_max_size: '500'
l_label: 'size/l'
l_max_size: '1000'
xl_label: 'size/xl'
fail_if_xl: 'false'
message_if_xl: 'This PR is very large. Consider breaking it into smaller PRs for easier review.'
files_to_ignore: 'pnpm-lock.yaml package-lock.json yarn.lock'
auto-label:
name: Auto Label
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: write
steps:
- name: Checkout repository
uses: actions/checkout@v7
- name: Label based on changed files
uses: actions/labeler@v7.0.0
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
configuration-path: .github/labeler.yml
changeset-check:
name: Check Changeset
runs-on: ubuntu-latest
# Two exemptions, both meaning "this PR declares no release of its own":
# - the `skip-changeset` label — the author's explicit opt-out;
# - the Changesets release PR (`changeset-release/main`, pushed by
# changesets/action). That PR is the CONSUMING side: it applies pending
# changesets into versions and CHANGELOGs and adds none, so the gate
# below can only ever fail it. It did, on every `chore: version
# packages` PR (#4422 / #4894), leaving the release blocked on a check
# that was structurally unsatisfiable.
# Pin the author as well as the branch name, so a hand-pushed branch of
# that name cannot borrow the exemption as an escape hatch.
if: >-
!contains(github.event.pull_request.labels.*.name, 'skip-changeset')
&& !(github.head_ref == 'changeset-release/main'
&& github.event.pull_request.user.login == 'github-actions[bot]')
permissions:
contents: read
pull-requests: write
steps:
- name: Checkout repository
uses: actions/checkout@v7
with:
fetch-depth: 0
- name: Setup Node.js
uses: actions/setup-node@v7
with:
node-version: '22'
- name: Enable Corepack
run: corepack enable
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Check for a changeset added by this PR
env:
BASE_SHA: ${{ github.event.pull_request.base.sha }}
run: |
if [ ! -d ".changeset" ]; then
echo "::warning::.changeset directory not found. Skipping changeset check."
exit 0
fi
# Count changesets THIS PR adds (diff against the base commit), NOT
# the whole .changeset directory. A global `find | wc -l` is unsound:
# in pre-release (RC) mode `changeset version` RETAINS every consumed
# .md file, so the directory is permanently non-empty and the gate can
# never go red. #3373 merged a real spec/api-surface fix with no
# changeset while this step happily reported "Found 104 changeset(s)".
# Diffing against BASE_SHA ignores that residue and sees only what the
# PR itself introduced.
#
# An empty-frontmatter changeset still COUNTS here, and that is
# deliberate and unchanged — it remains a legal "this PR releases
# nothing" declaration. What #5292 corrected is the PRESCRIPTION, not
# the count: this comment used to call it "on par with the
# skip-changeset label", and the failure message below used to offer
# the two as equals. They are not equal downstream. The label is a
# gate-level exemption that produces no input for changesets/action;
# an empty changeset is a real input to it. See the message for the
# consequence.
ADDED=$(git diff --name-only --diff-filter=A "$BASE_SHA" HEAD -- '.changeset/*.md' \
| grep -v '/README\.md$' | wc -l | tr -d '[:space:]')
if [ "$ADDED" -eq 0 ]; then
# The full comparison goes to the job log — that is what an author
# reading `gh run view --log-failed`, or expanding this step in the
# UI, actually sees. The ::error:: annotation after it is the
# one-line version for the Checks tab. Both lead with the label.
# Terminator sits at this block's base indentation on purpose: YAML
# strips that much from every line, so `MSG` lands in column 0 of
# the generated script. Do not re-indent it.
cat <<'MSG'
This PR adds no changeset. There are three ways forward, and they are NOT
equivalent. Pick by what the PR actually releases:
1. It releases something
-> run 'pnpm changeset' and name the packages it releases.
2. It releases nothing (.github/, .claude/, docs/, content/, examples/,
tests-only, and the like)
-> apply the 'skip-changeset' label. <<< PREFERRED
The label is a gate-level exemption. It produces NO input for
changesets/action, so it cannot affect a release.
3. An empty-frontmatter changeset also satisfies this gate and stays
legal -- but it is a LAST RESORT, not the quick way past a red check.
Unlike the label it is a REAL INPUT to changesets/action: when every
pending changeset is empty, the action takes its
"hasChangesets && !hasNonEmptyChangesets" branch, prints
"All changesets are empty; not creating PR", and returns in 0 seconds
-- no version PR, no publish, and the Release run still goes GREEN.
That is #4898, which silently stalled 17.0.0-rc.2. It also buys you
nothing the label does not: an empty changeset names no package, so
its body reaches no CHANGELOG.
If you are unsure, take route 2. A wrong 'skip-changeset' label is caught by
review; a wrong empty changeset is caught by nobody.
MSG
echo "::error::This PR adds no changeset. If it releases nothing, apply the 'skip-changeset' label (preferred); otherwise run 'pnpm changeset' and name the packages. An empty-frontmatter changeset also passes this gate, but it is NOT equivalent to the label -- it is a real input to changesets/action, and an all-empty set stalls the release silently and greenly (#4898). Full comparison in this step's log."
exit 1
fi
echo "This PR adds $ADDED changeset(s)."
- name: Guard against accidental major bumps (launch window)
# Every publishable package is in one Changesets "fixed" (lockstep) group,
# so a single `major` bump promotes the ENTIRE monorepo to a new major
# version. During the launch window we ship breaking changes as `minor`.
# Add the `allow-major` PR label when a whole-stack major is intended.
if: "!contains(github.event.pull_request.labels.*.name, 'allow-major')"
run: node scripts/check-changeset-no-major.mjs