Skip to content

Commit

Permalink
describe action metadata checks in document
Browse files Browse the repository at this point in the history
  • Loading branch information
rhysd committed Mar 19, 2024
1 parent 07878d5 commit 9c36f48
Show file tree
Hide file tree
Showing 5 changed files with 100 additions and 4 deletions.
74 changes: 74 additions & 0 deletions docs/checks.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ List of checks:
- [Contexts and special functions availability](#ctx-spfunc-availability)
- [Deprecated workflow commands](#check-deprecated-workflow-commands)
- [Conditions always evaluated to true at `if:`](#if-cond-always-true)
- [Action metadata syntax validation](#action-metadata-syntax)

Note that actionlint focuses on catching mistakes in workflow files. If you want some general code style checks, please consider
using a general YAML checker like [yamllint][].
Expand Down Expand Up @@ -2657,6 +2658,78 @@ works as intended.
actionlint checks all `if:` conditions in workflow and reports error when some condition is always evaluated to true due to extra
characters around `${{ }}`.

<a name="action-metadata-syntax"></a>
## Action metadata syntax validation

Example workflow input:

```yaml
on: push
jobs:
test:
runs-on: ubuntu-latest
steps:
# actionlint checks an action when it is actually used in a workflow
- uses: ./.github/actions/my-invalid-action
```

Example action metadata:

```yaml
# .github/actions/some-action/action.yml
name: 'My action'
author: '...'
# ERROR: 'description' section is required
runs:
# ERROR: Node.js runtime version is too old
using: 'node14'
# ERROR: The source file being run by this action does not exist
main: 'this-file-does-not-exist.js'
# ERROR: 'env' configuration is only allowed for Docker actions
env:
SOME_VAR: SOME_VALUE
```

Output:

```
test.yaml:8:15: description is required in metadata of "My action" action at "path/to/.github/actions/my-invalid-action/action.yml" [action]
|
8 | - uses: ./.github/actions/my-invalid-action
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
test.yaml:8:15: "node14" runner at "runs.using" is unavailable since the Node.js version is too old (14 < 16) in local action "My action" defined at "path/to/.github/actions/my-invalid-action". see https://docs.github.com/en/actions/creating-actions/metadata-syntax-for-github-actions#runs-for-javascript-actions [action]
|
8 | - uses: ./.github/actions/my-invalid-action
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
test.yaml:8:15: file "this-file-does-not-exist.js" does not exist in "path/to/.github/actions/my-invalid-action". it is specified at "main" key in "runs" section in "My action" action [action]
|
8 | - uses: ./.github/actions/my-invalid-action
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
test.yaml:8:15: "env" is not allowed in "runs" section because "My action" is a JavaScript action. the action is defined at "path/to/.github/actions/my-invalid-action" [action]
|
8 | - uses: ./.github/actions/my-invalid-action
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
```

All actions require a metadata file `action.yml` or `aciton.yaml`. The syntax is defined in [the official document][action-metadata-doc].

actionlint checks metadata files used in workflows and reports errors when they are not following the syntax.

- `name:`, `description:`, `runs:` sections are required
- Runner name at `using:` is one of `composite`, `docker`, `node16`, `node20`
- Keys under `runs:` section are correct. Required/Valid keys are different depending on the type of action; Docker action or
Composite action or JavaScript action (e.g. `image:` is required for Docker action).
- Files specified in some keys under `runs` are existing. For example, JavaScript action defines a script file path for
entrypoint at `main:`.

actionlint checks action metadata files which are used by workflows. Currently it is not supported to specify `action.yml`
directly via command line arguments.

Note that `steps` in Composite action's metadata is not checked at this point. It will be supported in the future.

---

[Installation](install.md) | [Usage](usage.md) | [Configuration](config.md) | [Go API](api.md) | [References](reference.md)
Expand Down Expand Up @@ -2710,3 +2783,4 @@ characters around `${{ }}`.
[deprecate-set-output-save-state]: https://github.blog/changelog/2022-10-11-github-actions-deprecating-save-state-and-set-output-commands/
[deprecate-set-env-add-path]: https://github.blog/changelog/2020-10-01-github-actions-deprecating-set-env-and-add-path-commands/
[workflow-commands-doc]: https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions
[action-metadata-doc]: https://docs.github.com/en/actions/creating-actions/metadata-syntax-for-github-actions
4 changes: 0 additions & 4 deletions rule_action.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,10 +105,6 @@ func (rule *RuleAction) invalidActionFormat(pos *Pos, spec string, why string) {
rule.Errorf(pos, "specifying action %q in invalid format because %s. available formats are \"{owner}/{repo}@{ref}\" or \"{owner}/{repo}/{path}@{ref}\"", spec, why)
}

func (rule *RuleAction) invalidRunsName(pos *Pos, name, action, path string) {
rule.Errorf(pos, "invalid runner name %q at runs.using in local action %q defined at %q. see https://docs.github.com/en/actions/creating-actions/metadata-syntax-for-github-actions#runs to know valid runner names", name, action, path)
}

func (rule *RuleAction) missingRunsProp(pos *Pos, prop, ty, action, path string) {
rule.Errorf(pos, `%q is required in "runs" section because %q is a %s action. the action is defined at %q`, prop, action, ty, path)
}
Expand Down
14 changes: 14 additions & 0 deletions testdata/examples/.github/actions/my-invalid-action/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# .github/actions/some-action/action.yml

name: 'My action'
author: '...'
# ERROR: 'description' section is required

runs:
# ERROR: Node.js runtime version is too old
using: 'node14'
# ERROR: The source file being run by this action does not exist
main: 'this-file-does-not-exist.js'
# ERROR: 'env' configuration is only allowed for Docker actions
env:
SOME_VAR: SOME_VALUE
4 changes: 4 additions & 0 deletions testdata/examples/action_metadata_syntax_validation.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
/test\.yaml:8:15: description is required in metadata of "My action" action at ".+(\\\\|/)my-invalid-action(\\\\|/)action\.yml" \[action\]/
/test\.yaml:8:15: invalid runner name \"node14\" at runs\.using in \"My action\" action defined at \".+(\\\\|/)actions(\\\\|/)my-invalid-action\"\. valid runners are \"composite\", \"docker\", \"node16\", and \"node20\"\. see https://.+ \[action\]/
/test\.yaml:8:15: file "this-file-does-not-exist\.js" does not exist in ".+(\\\\|/)my-invalid-action"\. it is specified at "main" key in "runs" section in "My action" action \[action\]/
/test\.yaml:8:15: "env" is not allowed in "runs" section because "My action" is a JavaScript action\. the action is defined at ".+(\\\\|/)my-invalid-action" \[action\]/
8 changes: 8 additions & 0 deletions testdata/examples/action_metadata_syntax_validation.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
on: push

jobs:
test:
runs-on: ubuntu-latest
steps:
# actionlint checks an action when it is actually used in a workflow
- uses: ./.github/actions/my-invalid-action

0 comments on commit 9c36f48

Please sign in to comment.