Skip to content

fix(ci): quote stylelint globs — the shell was capping the linter at one directory level - #783

Merged
rubenvdlinde merged 1 commit into
developmentfrom
fix/stylelint-unquoted-globs
Aug 11, 2026
Merged

fix(ci): quote stylelint globs — the shell was capping the linter at one directory level#783
rubenvdlinde merged 1 commit into
developmentfrom
fix/stylelint-unquoted-globs

Conversation

@rubenvdlinde

Copy link
Copy Markdown
Contributor

The defect: the shell ate the glob

package.json passed the stylelint globs unquoted:

"stylelint": "stylelint src/**/*.vue src/**/*.scss src/**/*.css",
"stylelint-fix": "stylelint src/**/*.vue src/**/*.scss src/**/*.css --fix",

Unquoted, the shell expands the pattern before stylelint is executed — stylelint receives a finished list of file paths and never does any globbing of its own. And bash without shopt -s globstar (npm scripts run under plain sh/bash, which does not set it) treats ** as an ordinary *. So src/**/*.vue expands to src/*/*.vue: exactly one directory level below src/.

Measured on this tree:

glob files handed to stylelint violations exit
src/**/*.vue … (unquoted, as shipped) 48 0 0 — green
'src/**/*.vue' … (quoted) 233 203 2

There are 231 .vue files and 2 .css files under src/. The npm stylelint job has therefore never looked below one directory level, and has been green for that reason — not because the styles were clean.

Quoting the globs hands the pattern through to stylelint, which does its own recursive globbing and actually walks src/.

What changed

Quoting the glob without fixing what it finds would just turn CI red, so both halves are in this one branch:

  1. Both stylelint and stylelint-fix scripts now single-quote their globs.
  2. All 203 violations fixed:
    • 202 × rule-empty-line-before — fixed with stylelint's own --fix (26 files, blank-line insertions only).
    • 1 × no-duplicate-selectorssrc/views/workflow-board/CaseCard.vue had two separate .case-card__header blocks (lines 220 and 243). Fixed by hand: the two blocks declared no overlapping properties, so they were merged into one, keeping padding-left: 26px (with a comment noting it reserves room for the absolutely-positioned .case-card__select checkbox). No declaration was dropped.

Nothing was weakened to get green: no .stylelintignore, no stylelint-disable comments, no .stylelintrc relaxation, no narrowed glob. The glob got wider.

After

$ stylelint 'src/**/*.vue' 'src/**/*.scss' 'src/**/*.css'
exit 0

-f json reports 233 file entries (231 .vue + 2 .css), 0 warnings — proving the wider scope really is being walked, not just passing quietly.

Planted true positive

A green check that has never failed proves nothing, so the new glob was tested against a deliberate defect placed deeper than one directory level — somewhere the old glob could not physically reach.

Removed one blank line in src/views/voorstellen/components/AuditTrail.vue (path depth 4; confirmed absent from the old glob's 48-file expansion). Then ran both commands against the identical working tree:

New (quoted) glob — catches it:

src/views/voorstellen/components/AuditTrail.vue
 139:1  ✖  Expected empty line before rule  rule-empty-line-before

1 problem (1 error, 0 warnings)
exit 2

Old (unquoted) glob — blind to it:

exit 0

The plant was then reverted; the tree is clean and exit 0 restored.


🤖 Generated with Claude Code

…ix the 203 violations it exposed

The stylelint scripts passed their globs UNQUOTED, so bash expanded them
before stylelint ever saw them. Bash without `globstar` treats `**` as a
single `*`, so `src/**/*.vue` expanded to `src/*/*.vue` — exactly one
directory level. Measured on this tree: 48 files matched, out of 233
stylable files under src/. The npm stylelint job has therefore never
looked deeper than one level and has always been green.

Quoting the globs hands them to stylelint, which does its own recursive
globbing.

- before (quoted): 233 files linted, 203 violations
  (202 rule-empty-line-before + 1 no-duplicate-selectors)
- after: 233 files linted, 0 violations, exit 0

The 202 rule-empty-line-before were fixed with stylelint's own --fix.
The no-duplicate-selectors in CaseCard.vue was merged by hand: two
.case-card__header blocks with no overlapping declarations, merged into
one, keeping padding-left.
@github-actions

Copy link
Copy Markdown
Contributor

Quality Report — ConductionNL/procest @ 6b8e6b5

Check PHP Vue Security License Tests
lint
phpcs
phpmd
psalm
phpstan
phpmetrics
eslint
stylelint
build
check-manifest
check-vue3-compile
test-l10n
composer ✅ 100/100
npm ✅ 552/552
PHPUnit
Newman ⏭️
Playwright
Hydra gates

Quality workflow — 2026-08-11 05:39 UTC

Download the full PDF report from the workflow artifacts.

@rubenvdlinde
rubenvdlinde merged commit 915d0fd into development Aug 11, 2026
32 checks passed
@rubenvdlinde
rubenvdlinde deleted the fix/stylelint-unquoted-globs branch August 11, 2026 05:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant