Skip to content

ci: inline shellcheck directives claim a linter that never runs #3688

Open

Description

Nothing in this repository runs shellcheck. There is no workflow under .github/workflows/ that invokes it, no Makefile target, and no hook in .pre-commit-config.yaml. The only trace of it in the tree is thirteen inline # shellcheck disable= directives inside the shell sources themselves.

That combination is worse than having no linter at all, and it is why this is worth filing rather than leaving as a gap. A # shellcheck disable=SC2086 sitting above a line is a claim: it says a reader considered the warning, judged it inapplicable here, and suppressed it deliberately. Every one of those thirteen is currently unbacked. A new one can be added with a wrong code, or against a warning that does not fire, or left behind after the code it excused was rewritten, and nothing anywhere reports it. The next person to read one has no way to tell a considered suppression from a decorative one.

There is a live example of the cost. hack/e2e-chainsaw/_lib/run-kubernetes.sh carries an SC2034 warning for an unused local port="$3" in run_kubernetes_test, whose third parameter is dead. It is harmless, it has been there for some time, and no run of anything would have surfaced it.

Two things would close this, and they are separable. Adding a shellcheck invocation over hack/**/*.sh, as a Makefile target wired into the same place the bats suites run, makes the existing directives mean what they say. Auditing the directives already in the tree against the warnings they claim to suppress is the second half, and it only becomes possible once the first exists.

Activity

  1. lexfrei commented on Aug 9, 2026

    @lexfrei
    ContributorAuthor

    Measured the baseline on one file so the claim above has a number attached rather than a direction. shellcheck 0.11.0 against hack/e2e-chainsaw/_lib/run-kubernetes.sh as it stands on main reports 16 findings:

    • 10x SC2086 (unquoted expansion)
    • 3x SC2016 (expressions in single quotes)
    • 1x SC2034 (an unused variable, port in run_kubernetes_test)
    • 2x SC1091 (sourced files not given as input)

    The last two are an artefact of invoking the tool without -x rather than a defect in the source, so the honest figure for this file is 14. None of them surfaces anywhere today, which is the point of this issue: the directives in the file declare a linter's judgement on code the linter never reads.

    Worth knowing before someone wires this up: a gate that starts at zero would have to either fix all fourteen first or carry a baseline, and the mix matters for that choice. SC2086 at ten occurrences is mostly mechanical, but at least one of them is load-bearing word splitting that must stay, so a blanket quoting pass would change behaviour. The SC2034 one is a genuinely dead variable that has been noticed by hand more than once.

  2. added
    kind/cleanupCategorizes issue or PR as related to cleanup of code, process, or technical debt
    area/ciIssues or PRs related to CI workflows, GitHub Actions, automation
    triage/acceptedIndicates an issue is ready to be actively worked on
    priority/backlogGeneral backlog priority. Lower than priority/important-longterm
    and removed
    triage/needs-triageIndicates an issue needs triage by a maintainer
    on Sep 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area/ciIssues or PRs related to CI workflows, GitHub Actions, automationkind/cleanupCategorizes issue or PR as related to cleanup of code, process, or technical debtpriority/backlogGeneral backlog priority. Lower than priority/important-longtermtriage/acceptedIndicates an issue is ready to be actively worked on

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions