Skip to content

P001 inline-tool

A run: step calls a build, test, lint or deploy tool directly instead of going through the task runner.

Severity: error; tolerated when a baseline allows it; allowed when an allow comment or config entry covers it.

# Taskfile.yml has a test task that runs `pnpm test`.
jobs:
web:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- name: Test
run: pnpm test
- name: Lint
run: npx eslint .
.github/workflows/ci.yml
7:14 P001 inline-tool step "Test" in job "web" runs 'pnpm test' directly; already available as 'task test'
9:14 P001 inline-tool step "Lint" in job "web" runs 'npx eslint .' directly

When a task runs the same command and nothing else, the message ends with “already available as” and the task to call. A task that also runs other commands, has dependencies or calls other tasks is never suggested, as calling it would run more than the step. Package runners such as npx, pnpm exec and uv run are looked through on both sides, so npx eslint . would match a task that runs eslint .. The task must also run in the step’s working-directory: a step in web/ matches a task with dir: web, not one that runs at the root.

The task is the definition of how to test or lint. A step that calls the tool directly keeps working after the task changes, so CI quietly runs something different from what task test runs locally.

  • Call the task: run: task test. ci-parity fix makes this change for you when it’s safe; see Fixing findings.
  • When no task exists yet, add one to the runner file and call it.

Allow the step with a reason, on its line or the line above:

- run: docker push ghcr.io/acme/widget-service:dev # ci-parity: allow images publish only from CI

Or allow a pattern in .ci-parity.yml, or stop flagging the tool with tools.remove; see Configuring.

Last reviewed: 2026-10-29