Skip to content

ci: actionlint does not lint composite actions under .github/actions/** #14632

Open

Description

@mrveiss

Summary

`.github/workflows/actionlint.yml` runs `rhysd/actionlint` but triggers only
on `.github/workflows/**` (both `push` and `pull_request` `paths` filters).
Composite action definitions under `.github/actions/*/action.yml` are outside
that trigger, so a change to one never runs actionlint at all today.

Why it matters

A composite action's own `runs.steps` accept a different, smaller key set than
a workflow step or a job (`run`, `shell`, `working-directory`, `env`, `id`,
`if`, `name`, plus `uses`/`with`). `timeout-minutes` — valid on a job and on a
workflow step — is not valid there. #14578 added it to one step of
`.github/actions/setup-python-suite/action.yml`, and GitHub's server-side
template validator rejected the whole file before a single step ran:

```
##[error]/.github/actions/setup-python-suite/action.yml (Line: 56, Col: 7): Unexpected value 'timeout-minutes'
##[error]GitHub.DistributedTask.ObjectTemplating.TemplateValidationException: The template is not valid.
```

Every python-suite shard that used the action failed identically. Nothing
local caught it — `code-quality` installs linters, not a validator for
GitHub's own workflow template schema, and no test in the repo executes a
composite action the way GitHub's runner does. #14578 added
`tools/lint/check_composite_action_step_keys.py` (a required `code-quality`
check, no external tool needed) to close this specific gap going forward, but
that is a hand-rolled allowed-key set for one narrow failure mode, not general
coverage of everything GitHub's schema would catch.

Two follow-ups, not yet done here

  1. Confirm what actionlint actually validates for composite actions.
    actionlint's primary target is workflow files; it is not verified (in this
    audit) whether pointing it at `.github/actions/*/action.yml` explicitly, or
    a specific invocation/config, gets composite-action step-key validation for
    free. If it does, that is stronger and more general coverage than the
    hand-rolled checker in fix(ci): guard requirements-ci drift and ansible-vs-CI system packages (#14550, #14551) #14578 and should run alongside or instead of it.
  2. Widen actionlint.yml's trigger paths to include
    `.github/actions/**` once (1) is confirmed, so a composite-action change
    gets linted at all.
  3. Consider promoting `actionlint` to a required check — it is not one of
    the 10 required contexts on `Dev_new_gui` today, so even after (2) it would
    flag but not block. That is an owner-level branch-protection decision, not
    something to change unilaterally.

Acceptance criteria

  • Determine whether actionlint validates composite-action step-key
    schemas (directly or via a specific flag/config), with evidence
  • If yes: widen `actionlint.yml`'s trigger to `.github/actions/**` and
    point actionlint at those files explicitly if needed
  • If no: note that explicitly, and keep
    `tools/lint/check_composite_action_step_keys.py` as the primary
    guard for this failure mode
  • Raise the required-check promotion as a decision for the owner, not a
    unilateral change

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions