Skip to content

fix(lint): use string comparison to dodge GHA == coercion#15

Merged
topcoder1 merged 1 commit into
mainfrom
chore/lint-input-skip-fix
May 1, 2026
Merged

fix(lint): use string comparison to dodge GHA == coercion#15
topcoder1 merged 1 commit into
mainfrom
chore/lint-input-skip-fix

Conversation

@topcoder1

Copy link
Copy Markdown
Owner

Summary

Critical fix for the reusable lint workflow's input-driven skip logic. Discovered while watching the install-fanout PRs (wxa-jake-ai#181 + wxa_vpn#180): both set `run_prettier: false` in the caller, but the prettier job ran anyway.

Root cause

GHA's `==` operator does loose-numeric coercion. `null` and `false` both coerce to `0`, so `false == null` evaluates to true. The previous condition

```yaml
if: ${{ inputs.run_prettier == null || inputs.run_prettier }}
```

was supposed to mean "run on self-test (input null) OR when explicitly true." But when the caller passed `run_prettier: false`, the `== null` clause matched (false coerces to null!) and the job always ran.

Fix

`format('{0}', inputs.X)` returns:

  • `''` when input is null (self-test)
  • `'true'` / `'false'` for explicit booleans

So:

```yaml
if: ${{ format('{0}', inputs.run_prettier) != 'false' }}
```

Context format result != 'false' Behavior
Self-test (pull_request) `''` true Run ✓
workflow_call run_X: true `'true'` true Run ✓
workflow_call run_X: false `'false'` false Skip ✓

Applied to:

  • actionlint job-level `if:` (run_actionlint)
  • prettier job-level `if:` (run_prettier)
  • install-deps step-level `if:` (install_node_deps)
  • shellcheck branch inside actionlint step (run_shellcheck)

After this lands

wxa-jake-ai#181 and wxa_vpn#180 will correctly skip the prettier job on next CI re-run.

🤖 Generated with Claude Code

GHA's `==` operator does loose-numeric coercion, so `false == null`
evaluates to TRUE (both coerce to 0). That defeated the previous
`inputs.X == null || inputs.X` skip-condition: when a caller passed
`run_prettier: false`, the `null` clause matched and the job ran
anyway. Verified on whois-api-llc/wxa-jake-ai#181 + wxa_vpn#180 —
both still ran prettier despite explicit run_prettier: false.

Switch to `format('{0}', inputs.X) != 'false'`:
  - self-test (inputs.X is null): format() → '' → '' != 'false' = true → run
  - workflow_call X=true: 'true' != 'false' = true → run
  - workflow_call X=false: 'false' != 'false' = false → skip

Same fix applied to:
  - actionlint job-level if (run_actionlint)
  - prettier job-level if (run_prettier)
  - install-deps step-level if (install_node_deps)
  - run_shellcheck check inside actionlint step (also was using
    the coercion-broken `== true && '...' || '...'` pattern)

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
@claude

claude Bot commented May 1, 2026

Copy link
Copy Markdown

No issues found. The format('{0}', inputs.X) != 'false' pattern is correct for all three input states (null → '', true → 'true', false → 'false'), and the shellcheck branch rewrite is semantically equivalent to the old ternary for all valid boolean inputs.

@topcoder1
topcoder1 merged commit 5aa06c8 into main May 1, 2026
3 checks passed
@topcoder1
topcoder1 deleted the chore/lint-input-skip-fix branch May 1, 2026 17:16
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