diff --git a/.yamllint.yaml b/.yamllint.yaml index a280c3e..dc117fc 100644 --- a/.yamllint.yaml +++ b/.yamllint.yaml @@ -11,6 +11,18 @@ extends: default ignore: | node_modules/ + # Lockfiles are generated, not authored. .prettierignore already + # exempts them under "Lockfiles, generated output"; yamllint not doing + # the same was an oversight that only stayed hidden because this repo + # has no lockfile. pnpm writes registry deprecation notices verbatim + # into pnpm-lock.yaml, which routinely exceeds the 140-char limit and + # cannot be rewrapped without invalidating the lockfile. + pnpm-lock.yaml + package-lock.json + yarn.lock + **/pnpm-lock.yaml + **/package-lock.json + **/yarn.lock rules: # 140-char limit. Workflow files have legitimately long shell URLs diff --git a/ADOPTING-LINT.md b/ADOPTING-LINT.md index e636c0b..10a6f2b 100644 --- a/ADOPTING-LINT.md +++ b/ADOPTING-LINT.md @@ -30,7 +30,8 @@ name: Lint on: pull_request: push: - branches: [main] + branches: [main, master, scaffold] + merge_group: workflow_dispatch: concurrency: @@ -45,6 +46,27 @@ jobs: uses: nyuchi/.github/.github/workflows/reusable-lint.yml@main ``` +Two things in that trigger list are load-bearing and must not be edited +per repo: + +- **`pull_request:` carries no `branches:` filter.** That filter matches + the PR's _base_ branch, so adding one silently stops the gate emitting + in any repo whose default branch is not `main` - `shamwari-core`, + `shamwari-gateway`, `shamwari-web` (`scaffold`) and `siafudb-kuzu` + (`master`). +- **The `push:` branch list names every default branch in the estate.** + 68 repos use `main`, `siafudb-kuzu` uses `master`, and + `shamwari-core`/`-gateway`/`-web` use `scaffold`. Drop a name and + merging to that repo's default branch fires nothing, so the contexts + never land on the default-branch head. It is a list rather than a bare + `push:` because unfiltered push would run the gate on every + feature-branch push in 74 repos and bill it twice per PR. +- **`merge_group:`** is what makes the gate work in a repo whose ruleset + uses a merge queue. Required checks must report on the + `gh-readonly-queue/**` ref and only `merge_group` produces that; + without it a queued PR stalls for the full `check_response_timeout` + and nothing can land. Harmless where there is no queue. + It is also offered in the GitHub UI under **Actions -> New workflow -> Org lint gate**, from `workflow-templates/lint.yml`. @@ -123,6 +145,35 @@ Two traps this gate has already been bitten by, both now fixed here: file that applies, and it prints any tracked file `.gitignore` would have hidden. +## Fixing violations: two things that will bite you + +**Never run `prettier --write` blind on `.mdx`.** Prettier 3.9.4's mdx +parser rewrites a multi-line `{/* ... */}` comment into `{/_ ... _/}` - +it reads the `*` as markdown emphasis and emits invalid MDX. The +formatter actively breaks the file. Single-line comments round-trip +fine, so rewrite an affected comment as a run of single-line +`{/* ... */}` comments: same text, valid MDX, prettier leaves it alone. +Always diff an `.mdx` file after `--write`. + +**A `.md` file containing MDX comments cannot satisfy both toolchains, +and `--fix` will corrupt it.** Mintlify starters leave `{/* ... */}` in a +file named `AGENTS.md`. Mintlify parses that file as MDX, where an HTML +comment is a parse error; markdownlint and Prettier read the same file as +Markdown, where the asterisks are emphasis - MD037 fires and Prettier +rewrites the marker to `_`. No spelling satisfies both. Worse, +`markdownlint-cli2 --fix` pairs the asterisks across adjacent comment +lines and emits `{/*Add product-specific terms and preferred usage _/}`, +which is neither valid MDX nor what anyone wrote. Decide which toolchain +owns the file: add it to `.mintignore` and use ordinary HTML comments, or +rename it to `.mdx`. + +**`markdownlint-cli2 --fix` will not fix MD036.** Emphasis used as a +heading needs a judgement call, not a rewrite. A bold line introducing a +subsection should become a real heading one level below its parent; a +sign-off or attribution in italics is not a heading at all and should +become a blockquote. Converting the second kind into a heading produces +a correct linter and a wrong document. + ## Language-specific CI This gate is the shared baseline that every repository can satisfy. diff --git a/workflow-templates/lint.yml b/workflow-templates/lint.yml index f766bb6..5e71cb6 100644 --- a/workflow-templates/lint.yml +++ b/workflow-templates/lint.yml @@ -23,7 +23,23 @@ name: Lint on: pull_request: push: - branches: [main] + # Every default-branch name in the estate: `main` covers 68 repos, + # `master` covers siafudb-kuzu, `scaffold` covers shamwari-core, + # shamwari-gateway and shamwari-web. Drop a name and merging to that + # repo's default branch fires nothing, so the five contexts never + # land on the default-branch head - which is how `lint / prettier` + # stayed red in bundu-labs/.github from 2026-05-02 unnoticed. + # + # A list rather than a bare `push:`, because unfiltered push would + # run the gate on every feature-branch push in 74 repos and bill it + # twice per PR. Add a name here if a repo ever adopts a fourth. + branches: [main, master, scaffold] + # Required for repos whose ruleset uses a MERGE QUEUE: required checks + # must report on the gh-readonly-queue/** ref, and only merge_group + # produces that. Without it a queued PR stalls for the full + # check_response_timeout and nothing can ever land. Harmless where + # there is no queue, so it stays in the one identical caller. + merge_group: workflow_dispatch: concurrency: