Categorygithub.com/rhysd/actionlint
modulepackage
1.7.1
Repository: https://github.com/rhysd/actionlint.git
Documentation: pkg.go.dev

# README

actionlint

CI Badge API Document

actionlint is a static checker for GitHub Actions workflow files. Try it online!

Features:

  • Syntax check for workflow files to check unexpected or missing keys following workflow syntax
  • Strong type check for ${{ }} expressions to catch several semantic errors like access to not existing property, type mismatches, ...
  • Actions usage check to check that inputs at with: and outputs in steps.{id}.outputs are correct
  • Reusable workflow check to check inputs/outputs/secrets of reusable workflows and workflow calls
  • shellcheck and pyflakes integrations for scripts at run:
  • Security checks; script injection by untrusted inputs, hard-coded credentials
  • Other several useful checks; glob syntax validation, dependencies check for needs:, runner label validation, cron syntax validation, ...

See the full list of checks done by actionlint.

actionlint reports 7 errors

Example of broken workflow:

on:
  push:
    branch: main
    tags:
      - 'v\d+'
jobs:
  test:
    strategy:
      matrix:
        os: [macos-latest, linux-latest]
    runs-on: ${{ matrix.os }}
    steps:
      - run: echo "Checking commit '${{ github.event.head_commit.message }}'"
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node_version: 18.x
      - uses: actions/cache@v4
        with:
          path: ~/.npm
          key: ${{ matrix.platform }}-node-${{ hashFiles('**/package-lock.json') }}
        if: ${{ github.repository.permissions.admin == true }}
      - run: npm install && npm test

actionlint reports 7 errors:

test.yaml:3:5: unexpected key "branch" for "push" section. expected one of "branches", "branches-ignore", "paths", "paths-ignore", "tags", "tags-ignore", "types", "workflows" [syntax-check]
  |
3 |     branch: main
  |     ^~~~~~~
test.yaml:5:11: character '\' is invalid for branch and tag names. only special characters [, ?, +, *, \, ! can be escaped with \. see `man git-check-ref-format` for more details. note that regular expression is unavailable. note: filter pattern syntax is explained at https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#filter-pattern-cheat-sheet [glob]
  |
5 |       - 'v\d+'
  |           ^~~~
test.yaml:10:28: label "linux-latest" is unknown. available labels are "windows-latest", "windows-2022", "windows-2019", "windows-2016", "ubuntu-latest", "ubuntu-22.04", "ubuntu-20.04", "ubuntu-18.04", "macos-latest", "macos-12", "macos-12.0", "macos-11", "macos-11.0", "macos-10.15", "self-hosted", "x64", "arm", "arm64", "linux", "macos", "windows". if it is a custom label for self-hosted runner, set list of labels in actionlint.yaml config file [runner-label]
   |
10 |         os: [macos-latest, linux-latest]
   |                            ^~~~~~~~~~~~~
test.yaml:13:41: "github.event.head_commit.message" is potentially untrusted. avoid using it directly in inline scripts. instead, pass it through an environment variable. see https://docs.github.com/en/actions/learn-github-actions/security-hardening-for-github-actions for more details [expression]
   |
13 |       - run: echo "Checking commit '${{ github.event.head_commit.message }}'"
   |                                         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
test.yaml:17:11: input "node_version" is not defined in action "actions/setup-node@v4". available inputs are "always-auth", "architecture", "cache", "cache-dependency-path", "check-latest", "node-version", "node-version-file", "registry-url", "scope", "token" [action]
   |
17 |           node_version: 18.x
   |           ^~~~~~~~~~~~~
test.yaml:21:20: property "platform" is not defined in object type {os: string} [expression]
   |
21 |           key: ${{ matrix.platform }}-node-${{ hashFiles('**/package-lock.json') }}
   |                    ^~~~~~~~~~~~~~~
test.yaml:22:17: receiver of object dereference "permissions" must be type of object but got "string" [expression]
   |
22 |         if: ${{ github.repository.permissions.admin == true }}
   |                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Why?

  • Running a workflow is time consuming. You need to push the changes and wait until the workflow runs on GitHub even if it contains some trivial mistakes. act is useful to debug the workflow locally. But it is not suitable for CI and still time consuming when your workflow gets larger.
  • Checks of workflow files by GitHub are very loose. It reports no error even if unexpected keys are in mappings (meant that some typos in keys). And also it reports no error when accessing to property which is actually not existing. For example matrix.foo when no foo is defined in matrix: section, it is evaluated to null and causes no error.
  • Some mistakes silently break a workflow. Most common case I saw is specifying missing property to cache key. In the case cache silently does not work properly but a workflow itself runs without error. So you might not notice the mistake forever.

Quick start

Install actionlint command by downloading the released binary or by Homebrew or by go install. See the installation document for more details like how to manage the command with several package managers or run via Docker container.

go install github.com/rhysd/actionlint/cmd/actionlint@latest

Basically all you need to do is run the actionlint command in your repository. actionlint automatically detects workflows and checks errors. actionlint focuses on finding out mistakes. It tries to catch errors as much as possible and make false positives as minimal as possible.

actionlint

Another option to try actionlint is the online playground. Your browser can run actionlint through WebAssembly.

See the usage document for more details.

Documents

  • Checks: Full list of all checks done by actionlint with example inputs, outputs, and playground links.
  • Installation: Installation instructions. Prebuilt binaries, Homebrew package, a Docker image, building from source, a download script (for CI) are available.
  • Usage: How to use actionlint command locally or on GitHub Actions, the online playground, an official Docker image, and integrations with reviewdog, Problem Matchers, super-linter, pre-commit, VS Code.
  • Configuration: How to configure actionlint behavior. Currently only labels of self-hosted runners can be configured.
  • Go API: How to use actionlint as Go library.
  • References: Links to resources.

Bug reporting

When you see some bugs or false positives, it is helpful to file a new issue with a minimal example of input. Giving me some feedbacks like feature requests or ideas of additional checks is also welcome.

License

actionlint is distributed under the MIT license.

# Packages

No description provided by the author
No description provided by the author

# Functions

ContainsExpression checks if the given string contains a ${{ }} placeholder or not.
EqualTypes returns if the two types are equal.
LexExpression lexes the given string as expression syntax.
NewEmptyObjectType creates new loose ObjectType instance which allows unknown props.
NewEmptyStrictObjectType creates new ObjectType instance which does not allow unknown props.
NewErrorFormatter creates new ErrorFormatter instance.
NewExprLexer makes new ExprLexer instance.
NewExprParser creates new ExprParser instance.
NewExprSemanticsChecker creates new ExprSemanticsChecker instance.
NewLinter creates a new Linter instance.
NewLocalActionsCache creates new LocalActionsCache instance for the given project.
NewLocalActionsCacheFactory creates a new LocalActionsCacheFactory instance.
NewLocalReusableWorkflowCache creates a new LocalReusableWorkflowCache instance for the given project.
NewLocalReusableWorkflowCacheFactory creates a new LocalReusableWorkflowCacheFactory instance.
NewMapObjectType creates new ObjectType which maps keys to a specific type value.
NewObjectType creates new loose ObjectType instance which allows unknown props with given props.
NewProject creates a new instance with a file path to the root directory of the repository.
NewProjects creates new Projects instance.
NewRuleAction creates new RuleAction instance.
NewRuleBase creates a new RuleBase instance.
NewRuleCredentials creates new RuleCredentials instance.
NewRuleDeprecatedCommands creates a new RuleDeprecatedCommands instance.
NewRuleEnvVar creates new RuleEnvVar instance.
NewRuleEvents creates new RuleEvents instance.
NewRuleExpression creates new RuleExpression instance.
NewRuleGlob creates new RuleGlob instance.
NewRuleID creates a new RuleID instance.
NewRuleIfCond creates new RuleIfCond instance.
NewRuleJobNeeds creates new RuleJobNeeds instance.
NewRuleMatrix creates new RuleMatrix instance.
NewRulePermissions creates new RulePermissions instance.
NewRulePyflakes creates new RulePyflakes instance.
NewRuleRunnerLabel creates new RuleRunnerLabel instance.
NewRuleShellcheck creates new RuleShellcheck instance.
NewRuleShellName creates new RuleShellName instance.
NewRuleWorkflowCall creates a new RuleWorkflowCall instance.
NewStrictObjectType creates new ObjectType instance which does not allow unknown props with given prop types.
NewUntrustedInputChecker creates a new UntrustedInputChecker instance.
NewUntrustedInputMap creates new instance of UntrustedInputMap.
NewVisitor creates Visitor instance.
Parse parses given source as byte sequence into workflow syntax tree.
ReadConfigFile reads actionlint config file (actionlint.yaml) from the given file path.
ValidatePathGlob checks a given input as glob pattern for file paths.
ValidateRefGlob checks a given input as glob pattern for Git ref names.
VisitExprNode visits the given expression syntax tree with given function f.
WorkflowKeyAvailability returns contexts and special functions availability of the given workflow key.

# Constants

ColorOptionKindAlways is kind to always colorize errors output.
ColorOptionKindAuto is kind to determine to colorize errors output automatically.
ColorOptionKindNever is kind never to colorize errors output.
CompareOpNodeKindEq is kind for == operator.
CompareOpNodeKindGreater is kind for > operator.
CompareOpNodeKindGreaterEq is kind for >= operator.
CompareOpNodeKindInvalid is invalid and initial value of CompareOpNodeKind values.
CompareOpNodeKindLess is kind for < operator.
CompareOpNodeKindLessEq is kind for <= operator.
CompareOpNodeKindNotEq is kind for != operator.
ExecKindAction is kind for step to run action.
ExecKindRun is kind for step to run shell script.
ExitStatusFailure is the exit status when the command stopped due to some fatal error while checking workflows.
ExitStatusInvalidCommandOption is the exit status when parsing command line options failed.
ExitStatusSuccessNoProblem is the exit status when the command ran successfully with no problem found.
ExitStatusSuccessProblemFound is the exit status when the command ran successfully with some problem found.
LogicalOpNodeKindAnd is a kind for && operator.
LogicalOpNodeKindInvalid is an invalid and initial value of LogicalOpNodeKind.
LogicalOpNodeKindOr is a kind for || operator.
LogLevelDebug shows all log output including debug information.
LogLevelNone does not output any log output.
LogLevelVerbose shows verbose log output.
RawYAMLValueKindArray is kind for an array value of raw YAML value.
RawYAMLValueKindObject is kind for an object value of raw YAML value.
RawYAMLValueKindString is kind for a string value of raw YAML value.
TokenKindAnd is a token for '&&'.
TokenKindComma is a token for ','.
TokenKindDot is a token for '.'.
TokenKindEnd is a token for end of token sequence.
TokenKindEq is a token for '=='.
TokenKindFloat is a token for float numbers.
TokenKindGreater is a token for '>'.
TokenKindGreaterEq is a token for '>='.
TokenKindIdent is a token for identifier.
TokenKindInt is a token for integers including hex integers.
TokenKindLeftBracket is a token for '['.
TokenKindLeftParen is a token for '('.
TokenKindLess is a token for '<'.
TokenKindLessEq is a token for '<='.
TokenKindNot is a token for '!'.
TokenKindNotEq is a token for '!='.
TokenKindOr is a token for '||'.
TokenKindRightBracket is a token for ']'.
TokenKindRightParen is a token for ')'.
TokenKindStar is a token for '*'.
TokenKindString is a token for string literals.
TokenKindUnknown is a default value of token as unknown token value.
WorkflowCallEventInputTypeBoolean represents boolean type input.
WorkflowCallEventInputTypeInvalid represents invalid type input as default value of the type.
WorkflowCallEventInputTypeNumber represents number type input.
WorkflowCallEventInputTypeString represents string type input.
WorkflowDispatchEventInputTypeBoolean is boolean type of input of workflow_dispatch event.
WorkflowDispatchEventInputTypeChoice is choice type of input of workflow_dispatch event.
WorkflowDispatchEventInputTypeEnvironment is environment type of input of workflow_dispatch event.
WorkflowDispatchEventInputTypeNone represents no type is specified to the input of workflow_dispatch event.
WorkflowDispatchEventInputTypeNumber is number type of input of workflow_dispatch event.
WorkflowDispatchEventInputTypeString is string type of input of workflow_dispatch event.

# Variables

AllWebhookTypes is a table of all webhooks with their types.
BrandingColors is a set of colors allowed at branding.color in action.yaml.
BrandingIcons is a set of icon names allowed at branding.icon in action.yaml.
BuiltinFuncSignatures is a set of all builtin function signatures.
BuiltinGlobalVariableTypes defines types of all global variables.
BuiltinUntrustedInputs is list of untrusted inputs.
OutdatedPopularActionSpecs is a spec set of known outdated popular actions.
PopularActions is data set of known popular actions.
SpecialFunctionNames is a map from special function name to available workflow keys.

# Structs

ActionMetadata represents structure of action.yaml.
ActionMetadataBranding is "branding" section of action.yaml.
ActionMetadataInput is input metadata in "inputs" section in action.yml metadata file.
ActionMetadataOutput is output metadata in "outputs" section in action.yml metadata file.
ActionMetadataRuns is "runs" section of action.yaml.
AnyType represents type which can be any type.
ArrayDerefNode represents elements dereference of arrays like '*' in 'foo.bar.*.piyo'.
ArrayType is type for arrays.
Bool represents generic boolean value in YAML file with position.
BoolNode is node for boolean literal, true or false.
BoolType is type for boolean values.
Command represents entire actionlint command.
CompareOpNode is node for binary expression to compare values; ==, !=, <, <=, > or >=.
Concurrency is a configuration of concurrency of the workflow.
Config is configuration of actionlint.
Container is configuration of how to run the container.
Credentials is credentials configuration.
Defaults is set of default configurations to run shell.
DefaultsRun is configuration that shell is how to be run.
DispatchInput is input specified on dispatching workflow manually.
Env represents set of environment variables.
Environment is a configuration of environment.
EnvVar represents key-value of environment variable setup.
Error represents an error detected by actionlint rules.
ErrorFormatter is a formatter to format a slice of ErrorTemplateFields.
ErrorTemplateFields holds all fields to format one error message.
ExecAction is configuration how to run action at the step.
ExecRun is configuration how to run shell script at the step.
ExprError is an error type caused by lexing/parsing expression syntax.
ExprLexer is a struct to lex expression syntax.
ExprParser is a parser for expression syntax.
ExprSemanticsChecker is a semantics checker for expression syntax.
Float represents generic float value in YAML file with position.
FloatNode is node for float literal.
FuncCallNode represents function call in expression.
FuncSignature is a signature of function, which holds return and arguments types.
IndexAccessNode is node for index access, which represents dynamic object property access or array index access.
Input is an input field for running an action.
Int represents generic integer value in YAML file with position.
IntNode is node for integer literal.
InvalidGlobPattern is an error on invalid glob pattern.
Job is configuration of how to run a job.
Linter is struct to lint workflow files.
LinterOptions is set of options for Linter instance.
LocalActionsCache is cache for local actions' metadata.
LocalActionsCacheFactory is a factory to create LocalActionsCache instances.
LocalReusableWorkflowCache is a cache for local reusable workflow metadata files.
LocalReusableWorkflowCacheFactory is a factory object to create a LocalReusableWorkflowCache instance per project.
LogicalOpNode is node for logical binary operators; && or ||.
Matrix is matrix variations configuration of a job.
MatrixAssign represents which value should be taken in the row of the matrix.
MatrixCombination is combination of matrix value assignments to define one of matrix variations.
MatrixCombinations is list of combinations of matrix assignments used for 'include' and 'exclude' sections.
MatrixRow is one row of matrix.
NotOpNode is node for unary ! operator.
NullNode is node for null literal.
NullType is type for null value.
NumberType is type for number values such as integer or float.
ObjectDerefNode represents property dereference of object like 'foo.bar'.
ObjectType is type for objects, which can hold key-values.
Output is output entry of the job.
Permissions is set of permission configurations in workflow file.
PermissionScope is struct for respective permission scope like "issues", "checks", ..
Pos represents position in the file.
Project represents one GitHub project.
Projects represents set of projects.
RawYAMLArray is raw YAML sequence value.
RawYAMLObject is raw YAML mapping value.
RawYAMLString is raw YAML scalar value.
RepositoryDispatchEvent is repository_dispatch event configuration.
ReusableWorkflowMetadata is metadata to validate local reusable workflows.
ReusableWorkflowMetadataInput is an input metadata for validating local reusable workflow file.
ReusableWorkflowMetadataOutput is an output metadata for validating local reusable workflow file.
ReusableWorkflowMetadataSecret is a secret metadata for validating local reusable workflow file.
RuleAction is a rule to check running action in steps of jobs.
RuleBase is a struct to be a base of rule structs.
RuleCredentials is a rule to check credentials in workflows.
RuleDeprecatedCommands is a rule checker to detect deprecated workflow commands.
RuleEnvVar is a rule checker to check environment variables setup.
RuleEvents is a rule to check 'on' field in workflow.
RuleExpression is a rule checker to check expression syntax in string values of workflow syntax.
RuleGlob is a rule to check glob syntax.
RuleID is a rule to check step IDs in workflow.
RuleIfCond is a rule to check if: conditions.
RuleJobNeeds is a rule to check 'needs' field in each job configuration.
RuleMatrix is a rule checker to check 'matrix' field of job.
RulePermissions is a rule checker to check permission configurations in a workflow.
RulePyflakes is a rule to check Python scripts at 'run:' using pyflakes.
RuleRunnerLabel is a rule to check runner label like "ubuntu-latest".
RuleShellcheck is a rule to check shell scripts at 'run:' using shellcheck.
RuleShellName is a rule to check 'shell' field.
RuleWorkflowCall is a rule checker to check workflow call at jobs.<job_id>.
Runner is struct for runner configuration.
ScheduledEvent is event scheduled by workflow.
Service is configuration to run a service like database.
Services is a mapping from service ID to its configuration.
Step is step configuration.
Strategy is strategy configuration of how the job is run.
String represents generic string value in YAML file with position.
StringNode is node for string literal.
StringType is type for string values.
Token is a token lexed from expression syntax.
UntrustedInputChecker is a checker to detect untrusted inputs in an expression syntax tree.
UntrustedInputMap is a recursive map to match context object property dereferences.
VariableNode is node for variable access.
Visitor visits syntax tree from root in depth-first order.
WebhookEvent represents event type based on webhook events.
WebhookEventFilter is a filter for Webhook events such as 'branches', 'paths-ignore', ..
Workflow is root of workflow syntax tree, which represents one workflow configuration file.
WorkflowCall is a struct to represent workflow call at jobs.<job_id>.
WorkflowCallEvent is workflow_call event configuration.
WorkflowCallEventInput is an input configuration of workflow_call event.
WorkflowCallEventOutput is an output configuration of workflow_call event.
WorkflowCallEventSecret is a secret configuration of workflow_call event.
WorkflowCallInput is a normal input for workflow call.
WorkflowCallSecret is a secret input for workflow call.
WorkflowDispatchEvent is event on dispatching workflow manually.

# Interfaces

Event interface represents workflow events in 'on' section.
Exec is an interface how the step is executed.
ExprNode is a node of expression syntax tree.
ExprType is interface for types of values in expression.
Pass is an interface to traverse a workflow syntax tree.
RawYAMLValue is a value at matrix variation.
Rule is an interface which all rule structs must meet.

# Type aliases

ActionMetadataInputs is a map from input ID to its metadata.
ActionMetadataOutputs is a map from output ID to its metadata.
ByErrorPosition is predicate for sort.Interface.
ColorOptionKind is kind of colorful output behavior.
CompareOpNodeKind is a kind of compare operators; ==, !=, <, <=, >, >=.
ExecKind is kind of how the step is executed.
LogicalOpNodeKind is a kind of logical operators; && and ||.
LogLevel is log level of logger used in Linter instance.
RawYAMLValueKind is kind of raw YAML values.
ReusableWorkflowMetadataInputs is a map from input name to reusable wokflow input metadata.
ReusableWorkflowMetadataOutputs is a map from output name to reusable wokflow output metadata.
ReusableWorkflowMetadataSecrets is a map from secret name to reusable wokflow secret metadata.
TokenKind is kind of token.
UntrustedInputSearchRoots is a list of untrusted inputs.
VisitExprNodeFunc is a visitor function for VisitExprNode().
WorkflowCallEventInputType is a type of inputs at workflow_call event.
WorkflowDispatchEventInputType is a type for input types of workflow_dispatch events.