Skip to content

fix(plugin-grid): the cross-page select-all banner works under external pagination (#4464) #1332

fix(plugin-grid): the cross-page select-all banner works under external pagination (#4464)

fix(plugin-grid): the cross-page select-all banner works under external pagination (#4464) #1332

Workflow file for this run

name: Control Bytes
# Why this is its own workflow instead of a job in `ci.yml` or `lint.yml`: on a
# markdown-only change neither of those runs anything expensive, so a gate living
# inside one of them would never see it. A raw control byte lands in markdown
# exactly as easily as in TypeScript — objectstack#4890 was a NUL in a `.claude/`
# skill file, emitted by the very PR that was writing the rule against it — so a
# gate that cannot see a markdown-only PR rebuilds the hole it exists to close.
# `changeset-guard.yml` sits in this repo for the same reason and says so in its
# own header.
#
# That is no longer the reason this header used to give, and objectui#4381
# corrected it. It said both of those workflows list `'**/*.md'`, `content/**`,
# `docs/**` and `.changeset/**` under `paths-ignore`, with no per-job path filter
# available in GitHub Actions, so a markdown-only PR started neither.
# objectui#3523 step 2 deleted `paths-ignore` from their `pull_request` trigger;
# it remains ONLY on `push`. Such a PR does start both workflows and does produce
# their contexts — measured: PR #3856 (one markdown file) 16 checks, PR #4339
# (one line added to AGENTS.md) 17. The correction is objectui#3857; an author
# had already acted on the old sentence and got the opposite result.
#
# What #3523 moved rather than deleted is the path DECISION: it is now the
# `Decide whether this change needs a full run` step in `ci.yml`, with a twin in
# `lint.yml`, and its exclusion list is that `push` filter unchanged — markdown
# among it, held identical to it by
# `scripts/__tests__/merge-queue-reporting.test.ts`. Both workflows therefore
# start, report, and skip every expensive step on a markdown-only PR, and both
# still skip the run outright on a markdown-only push to `main`. The conclusion
# outlived its premise: this gate has to run outside that in-job switch.
#
# Hence: no `paths` and no `paths-ignore` here, deliberately.
# `scripts/__tests__/check-control-bytes.test.ts` fails if either is ever added.
#
# It needs no install and no build — a checkout plus one `node` call over
# `git ls-files`, a few seconds — so keep it that way if you add checks to it.
on:
pull_request:
branches: [main, develop]
push:
branches: [main, develop]
# Merge queue (objectui#3523 — see `ci.yml`'s trigger block for the full note
# and the measurements behind it). This repository's queue is enforced by a
# ruleset but had zero `merge_group` subscribers, so its required-check set
# could only ever be empty. This gate is one of the two the audit found safe
# to require today — deliberately unfiltered, so it reports on every shape of
# pull request — and a required check that does not report on a queue build
# stalls the queue until the ruleset's 60-minute timeout fails it. `types:` is
# named although `checks_requested` is currently the only one GitHub defines.
merge_group:
types: [checks_requested]
workflow_dispatch:
concurrency:
group: control-bytes-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
permissions:
contents: read
jobs:
control-bytes:
name: Control Byte Scan
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- name: Checkout code
uses: actions/checkout@v7
- name: Setup Node.js
uses: actions/setup-node@v7
with:
node-version: '22.x'
# A single raw U+0000 makes grep and ripgrep classify the whole file as
# binary and print no matching lines at all, so the file drops out of code
# search and out of every grep-based lint — with no error to say so. git
# will not warn either: it decides binary-ness from the first 8000 bytes
# only. Reads `git ls-files`, so no install is required.
- name: Scan tracked text files for raw control bytes
run: node scripts/check-control-bytes.mjs