Skip to content

Latest commit

 

History

History
1731 lines (1491 loc) · 103 KB

CHANGELOG.md

File metadata and controls

1731 lines (1491 loc) · 103 KB

v1.7.0 - 08 May 2024

  • From this version, actionlint starts to check action metadata file action.yml (or action.yaml). At this point, only very basic checks are implemented and contents of steps: are not checked yet.
    • It checks properties under runs: section (e.g. main: can be specified when it is a JavaScript action), branding: properties, and so on.
      name: 'My action'
      author: '...'
      # ERROR: 'description' section is missing
      
      branding:
        # ERROR: Invalid icon name
        icon: dog
      
      runs:
        # ERROR: Node.js runtime version is too old
        using: 'node12'
        # 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
    • actionlint still focuses on checking workflow files. So there is no way to directly specify action.yml as an argument of actionlint command. actionlint checks all local actions which are used by given workflows. If you want to use actionlint for your action development, prepare a test/example workflow which uses your action, and check it with actionlint instead.
    • Checks for steps: contents are planned to be implemented. Since several differences are expected between steps: in workflow file and steps: in action metadata file (e.g. available contexts), the implementation is delayed to later version. And the current implementation of action metadata parser is ad hoc. I'm planning a large refactorying and breaking changes Go API around it are expected.
  • Add runner.environment property. (#412)
    - run: echo 'Run by GitHub-hosted runner'
      if: runner.environment == 'github-hosted'
  • Using outdated popular actions is now detected at error. See the document for more details.
    • Here 'outdated' means actions which use runtimes no longer supported by GitHub-hosted runners such as node12.
      # ERROR: actions/checkout@v2 is using the outdated runner 'node12'
      - uses: actions/checkout@v2
  • Support attestations permission which was recently added to GitHub Actions as beta. (#418, thanks @bdehamer)
    permissions:
      id-token: write
      contents: read
      attestations: write
  • Check comparison expressions more strictly. Arbitrary types of operands can be compared as the official document explains. However, comparisons between some types are actually meaningless because the values are converted to numbers implicitly. actionlint catches such meaningless comparisons as errors. Please see the check document for more details.
    on:
      workflow_call:
        inputs:
          timeout:
            type: boolean
    
    jobs:
      test:
        runs-on: ubuntu-latest
        steps:
          - run: echo 'called!'
            # ERROR: Comparing string to object is always evaluated to false
            if: ${{ github.event == 'workflow_call' }}
          - run: echo 'timeout is too long'
            # ERROR: Comparing boolean value with `>` doesn't make sense
            if: ${{ inputs.timeout > 60 }}
  • Follow the update that macos-latest is now an alias to macos-14 runner.
  • Support a custom python shell by pyflakes rule.
  • Add workaround actionlint reports that dorny/paths-filter's predicate-quantifier input is not defined. (#416)
  • Fix the type of a conditional expression by comparison operators is wider than expected by implementing type narrowing. (#384)
    • For example, the type of following expression should be number but it was actually string | number and actionlint complained that timeout-minutes must take a number value.
      timeout-minutes: ${{ env.FOO && 10 || 60 }}
  • Fix ${{ }} placeholder is not available at jobs.<job_id>.services. (#402)
    jobs:
      test:
        services: ${{ fromJSON('...') }}
        runs-on: ubuntu-latest
        steps:
          - run: ...
  • Do not check outputs of google-github-actions/get-secretmanager-secrets because this action sets outputs dynamically. (#404)
  • Fix defaults.run is ignored on detecting the shell used in run:. (#409)
    defaults:
      run:
        shell: pwsh
    jobs:
      test:
        runs-on: ubuntu-latest
        steps:
          # This was wrongly detected as bash script
          - run: $Env:FOO = "FOO"
  • Fix parsing a syntax error reported from pyflakes when checking a Python script in run:. (#411)
    - run: print(
      shell: python
  • Skip checking exclude: items in matrix: when they are constructed from ${{ }} dynamically. (#414)
    matrix:
      foo: ['a', 'b']
      exclude:
        # actionlint complained this value didn't exist in matrix combinations
        - foo: ${{ env.EXCLUDE_FOO }}
  • Fix checking exclude: items when ${{ }} is used in items of nested arrays.
    matrix:
      foo:
        - ["${{ fromJSON('...') }}"]
      exclude:
        # actionlint complained this value didn't match to any matrix combinations
        - foo: ['foo']
  • Update popular actions data set. New major versions are added and the following actions are newly added.
    • peaceiris/actions-hugo
    • actions/attest-build-provenance
    • actions/add-to-project
    • octokit/graphql-action
  • Update Go dependencies to the latest.
  • Reduce the size of actionlint executable by removing redundant data from popular actions data set.
    • x86_64 executable binary size was reduced from 6.9MB to 6.7MB (2.9% smaller).
    • Wasm binary size was reduced from 9.4MB to 8.9MB (5.3% smaller).
  • Describe how to integrate actionlint to Pulsar Edit in the document. (#408, thanks @mschuchard)
  • Update outdated action versions in the usage document. (#413, thanks @naglis)

Changes

v1.6.27 - 24 Feb 2024

  • Add macOS 14 runner labels for Apple Silicon support. The following labels are added. (thanks @harryzcy, #392)
    • macos-14
    • macos-14-xlarge
    • macos-14-large
  • Remove ubuntu-18.04 runner label from runners list since it is no longer supported. (#363)
  • Allow glob patterns in self-hosted-runner.labels configuration. For example, the following configuration defines any runner labels prefixed with private-linux-. (thanks @kishaningithub, #378)
    self-hosted-runner:
        labels:
          - private-linux-*
  • Fix a race condition bug when -format option is used for linting multiple workflow files. Thanks @ReinAchten-TomTom for your help on the investigation. (#370)
  • Fix a race condition due to conflicts between some goroutine which starts to run shellcheck process and other goroutine which starts to wait until all processes finish.
  • The popular actions data set was updated to the latest and the following actions were newly added. (thanks @jmarshall, #380)
    • google-github-actions/auth
    • google-github-actions/get-secretmanager-secrets
    • google-github-actions/setup-gcloud
    • google-github-actions/upload-cloud-storage
    • pulumi/actions
    • pypa/gh-action-pypi-publish
  • Add support for larger runner labels. The following labels are added. (thanks @therealdwright, #371)
    • windows-latest-8-cores
    • ubuntu-latest-4-cores
    • ubuntu-latest-8-cores
    • ubuntu-latest-16-cores
  • The following WebHook types are supported for pull_request event.
    • enqueued
    • dequeued
    • milestoned
    • demilestoned
  • Explain how to control shellckeck behavior in the shellcheck rule document. Use SHELLCHECK_OPTS environment variable to pass arguments to shellcheck. See the shellcheck's official document for more details.
    # Enable some optional rules
    SHELLCHECK_OPTS='--enable=avoid-nullary-conditions' actionlint
    # Disable some rules
    SHELLCHECK_OPTS='--exclude=SC2129' actionlint
    
  • Explicitly specify docker.io host name in pre-commit hook. (thanks @gotmax23, #382)
  • Explain how to report issues and send patches in CONTRIBUTING.md.
  • Fix the link to super-linter project. (thanks @zkoppert, #376)
  • Add the instruction to install actionlint via the Arch Linux's official repository. (thanks @sorairolake, #381)
  • Prefer fixed revisions in the pre-commit usage. (thanks @corneliusroemer, #354)
  • Add instructions to use actionlint with Emacs. (thanks @tirimia, #341)
  • Add instructions to use actionlint with Vim and Neovim text editors.
  • Add actionlint.RuleBase.Config method to get the actionlint configuration passed to rules. (thanks @hugo-syn, #387)
  • Add actionlint.ContainsExpression function to check if the given string contains ${{ }} placeholders or not. (thanks @hugo-syn, #388)
  • Support Go 1.22 and set the minimum supported Go version to 1.18 for x/sys package.
  • Update Go dependencies to the latest.

Changes

v1.6.26 - 18 Sep 2023

  • Several template fields and template actions were added. All fields and actions are listed in the document. Please read it for more details. (#311)
    • By these additions, now actionlint can output the result in the SARIF format. SARIF is a format for the output of static analysis tools used by GitHub CodeQL. the example Go template to format actionlint output in SARIF.
      actionlint -format "$(cat /path/to/sarif_template.txt)" > output.json
    • allKinds returns the kinds (lint rules) information as an array. You can include what lint rules are defined in the command output.
    • toPascalCase converts snake case (foo_bar) or kebab case (foo-bar) into pascal case (FooBar).
  • Report an error when the condition at if: is always evaluated to true. See the check document to know more details. (#272)
    # ERROR: All the following `if:` conditions are always evaluated to true
    - run: echo 'Commit is pushed'
      if: |
        ${{ github.event_name == 'push' }}
    - run: echo 'Commit is pushed'
      if: "${{ github.event_name == 'push' }} "
    - run: echo 'Commit is pushed to main'
      if: ${{ github.event_name == 'push' }} && ${{ github.ref_name == 'main' }}
  • Fix actionlint didn't understand ${{ }} placeholders in environment variable names. (#312)
    env:
      "${{ steps.x.outputs.value }}": "..."
  • Fix type of matrix row when some expression is assigned to it with ${{ }} (#285)
    strategy:
      matrix:
        test:
          # Matrix rows are assigned from JSON string
          - ${{ fromJson(inputs.matrix) }}
    steps:
      - run: echo ${{ matrix.test.foo.bar }}
  • Fix checking exclude of matrix was incorrect when some matrix row is dynamically constructed with ${{ }}. (#261)
    strategy:
      matrix:
        build-type:
          - debug
          - ${{ fromJson(inputs.custom-build-type) }}
        exclude:
          # 'release' is not listed in 'build-type' row, but it should not be reported as error
          # since the second row of 'build-type' is dynamically constructed with ${{ }}.
          - build-type: release
  • Fix checking exclude of matrix was incorrect when object is nested at row of the matrix. (#249)
    matrix:
      os:
        - name: Ubuntu
          matrix: ubuntu
        - name: Windows
          matrix: windows
      arch:
        - name: ARM
          matrix: arm
        - name: Intel
          matrix: intel
      exclude:
        # This should exclude { os: { name: Windows, matrix: windows }, arch: {name: ARM, matrix: arm } }
        - os:
            matrix: windows
          arch:
            matrix: arm
  • Fix data race when actionlint.yml config file is used by multiple goroutines to check multiple workflow files. (#333)
  • Check keys' case sensitivity. (#302)
    steps:
      # ERROR: 'run:' is correct
      - ruN: echo "hello"
  • Add number as input type of workflow_dispatch event. (#316)
  • Check max number of inputs of workflow_dispatch event is 10.
  • Check numbers at timeout-minutes and max-parallel are greater than zero.
  • Add Go APIs to define a custom rule. Please read the code example to know the usage.
    • Make some RuleBase methods public which are useful to implement your own custom rule type. (thanks @hugo-syn, #327, #331)
    • OnRulesCreated field is added to LinterOptions struct. You can modify applied rules with the hook (add your own rule, remove some rule, ...).
  • Add NewProject() Go API to create a Project instance.
  • Fix tests failed when sources are downloaded from .tar.gz link. (#307)
  • Improve the pre-commit document to explain all pre-commit hooks by this repository.
  • Clarify the regular expression syntax of -ignore option is RE2. (#320)
  • Use ubuntu-latest runner to create winget release. (thanks @sitiom, #308)
  • Update popular actions data set, available contexts, webhook types to the latest.
  • Use Go 1.21 to build release binaries.
  • Update Go dependencies to the latest. (thanks @harryzcy, #322)

Changes

v1.6.25 - 15 Jun 2023

  • Parse new syntax at runs-on:. Now runs-on: can have group: and labels: configurations. Please read the official document for more details. (#280)
    runs-on:
      group: ubuntu-runners
      labels: ubuntu-20.04-16core
  • Add support for macOS XL runners. macos-latest-xl, macos-13-xl, macos-12-xl labels are available at runs-on:. (#299, thanks @woa7)
  • Find Git project directory from -stdin-filename command line argument. Even if the workflow content is passed via stdin, actionlint can recognize reusable workflows depended by the workflow using file path passed at -stdin-filename argument. (#283)
  • Fix order of errors is not deterministic when multiple errors happen at the same location (file name, line number, column number). It happens only when building actionlint with Go 1.20 or later.
  • Fix type name of watch webhook.
  • Fix type of matrix row (property of matrix context) when ${{ }} is used in the row value. (#294)
  • Fix go install ./... doesn't work. (#297)
  • Update actionlint pre-commit hook to use Go toolchain. Now pre-commit automatically installs actionlint command so you don't need to install it manually. Note that this hook requires pre-commit v3.0.0 or later. For those who don't have Go toolchain, the previous hook is maintained as actionlint-system hook. Please read the document to know the usage details. (#301, thanks @Freed-Wu and @dokempf)
  • Update Go dependencies to the latest.
  • Update npm dependencies for playground to the latest and fix optimizing Wasm binary with wasm-opt.
  • Update popular actions data set. New major versions and new inputs of many popular actions are now supported like sparse-checkout input of actions/checkout action. (#305)
  • Fix outdated document for Problem Matchers. (#289, thanks @carlcsaposs-canonical)
  • Fix outdated links in document for super-linter. (#303, thanks @gmacario)
  • Automate releasing the Winget package with GitHub Actions. (#276, #293, thanks @sitiom)

Changes

v1.6.24 - 04 Apr 2023

Changes

v1.6.23 - 19 Jan 2023

  • Fix using vars context causes 'undefined context' error. This context is for 'Variables' feature which was recently added to GitHub Actions. (#260)
    - name: Use variables
      run: |
        echo "repository variable : ${{ vars.REPOSITORY_VAR }}"
        echo "organization variable : ${{ vars.ORGANIZATION_VAR }}"
        echo "overridden variable : ${{ vars.OVERRIDE_VAR }}"
        echo "variable from shell environment : $env_var"
  • Fix 'no property' error on accessing some github context's properties which were added recently. (#259)
  • Update popular actions data set and add some new actions to it
  • Playground is improved by making the right pane sticky. It is useful when many errors are reported. (#253, thanks @ericcornelissen)
  • Update Go modules dependencies and playground dependencies

Changes

v1.6.22 - 01 Nov 2022

  • Detect deprecated workflow commands such as set-output or save-state and suggest the alternative. See the document for more details. (#234)
    # ERROR: This format of 'set-output' workflow command was deprecated
    - run: echo '::set-output name=foo::bar'
  • Fix that ${{ }} expression at on.workflow_call.inputs.<id>.default caused an error. (#235)
    on:
      workflow_call:
        inputs:
          project:
            type: string
            # OK: The default value is generated dynamically
            default: ${{ github.event.repository.name }}
  • Improve type of inputs context to grow gradually while checking inputs in workflow_call event.
    on:
      workflow_call:
        inputs:
          input1:
            type: string
            # ERROR: `input2` is not defined yet
            default: ${{ inputs.input2 }}
          input2:
            type: string
            # OK: `input1` was already defined above
            default: ${{ inputs.input1 }}
  • Check types of default values of workflow call inputs even if ${{ }} expression is used.
    on:
      workflow_call:
        inputs:
          input1:
            type: boolean
          input2:
            type: number
            # ERROR: Boolean value cannot be assigned to number
            default: ${{ inputs.input1 }}
  • Fix the download script is broken since GHE server does not support the new set-output format yet. (#240)
  • Replace the deprecated set-output workflow command in our own workflows. (#239, thanks @Mrtenz)
  • Popular actions data set was updated to the latest as usual.

Changes

v1.6.21 - 09 Oct 2022

  • Check contexts availability. Some contexts limit where they can be used. For example, jobs.<job_id>.env workflow key does not allow accessing env context, but jobs.<job_id>.steps.env allows. See the official document for the complete list of contexts availability. (#180)
    ...
    
    env:
      TOPLEVEL: ...
    
    jobs:
      test:
        runs-on: ubuntu-latest
        env:
          # ERROR: 'env' context is not available here
          JOB_LEVEL: ${{ env.TOPLEVEL }}
        steps:
          - env:
              # OK: 'env' context is available here
              STEP_LEVEL: ${{ env.TOPLEVEL }}
            ...
    actionlint reports the context is not available and what contexts are available as follows:
    test.yaml:11:22: context "env" is not allowed here. available contexts are "github", "inputs", "matrix", "needs", "secrets", "strategy". see https://docs.github.com/en/actions/learn-github-actions/contexts#context-availability for more details [expression]
       |
    11 |       JOB_LEVEL: ${{ env.TOPLEVEL }}
       |                      ^~~~~~~~~~~~
    
  • Check special functions availability. Some functions limit where they can be used. For example, status functions like success() or failure() are only available in conditions of if:. See the official document for the complete list of special functions availability. (#214)
    ...
    
    steps:
      # ERROR: 'success()' function is not available here
      - run: echo 'Success? ${{ success() }}'
        # OK: 'success()' function is available here
        if: success()
    actionlint reports success() is not available and where the function is available as follows:
    test.yaml:8:33: calling function "success" is not allowed here. "success" is only available in "jobs.<job_id>.if", "jobs.<job_id>.steps.if". see https://docs.github.com/en/actions/learn-github-actions/contexts#context-availability for more details [expression]
      |
    8 |       - run: echo 'Success? ${{ success() }}'
      |                                 ^~~~~~~~~
    
  • Fix inputs context is not available in run-name: section. (#223)
  • Allow dynamic shell configuration like shell: ${{ env.SHELL }}.
  • Fix no error is reported when on: does not exist at toplevel. (#232)
  • Fix an error position is not correct when the error happens at root node of workflow AST.
  • Fix an incorrect empty event is parsed when on: section is empty.
  • Fix the error message when parsing an unexpected key on toplevel. (thanks @norwd, #231)
  • Add in_progress type to workflow_run webhook event trigger.
  • Describe the actionlint extension for Nova.app in the usage document. (thanks @jbergstroem, #222)
  • Note Super-Linter uses a different place for configuration file. (thanks @per-oestergaard, #227)
  • Add actions/setup-dotnet@v3 to popular actions data set.
  • generate-availability script was created to scrape the information about contexts and special functions availability from the official document. The information can be used through actionlint.WorkflowKeyAvailability() Go API. This script is run once a week on CI to keep the information up-to-date.

Changes

v1.6.20 - 30 Sep 2022

  • Support run-name which GitHub introduced recently. It is a name of workflow run dynamically configured. See the official document for more details. (#220)
    on: push
    run-name: Deploy by @${{ github.actor }}
    
    jobs:
      ...
  • Add end_column property to JSON representation of error. The property indicates a column of the end position of ^~~~~~~ indicator in snippet. Note that end_column is equal to column when the indicator cannot be shown. (#219)
    $ actionlint -format '{{json .}}' test.yaml | jq
    [
      {
        "message": "property \"unknown_prop\" is not defined in object type {arch: string; debug: string; name: string; os: string; temp: string; tool_cache: string; workspace: string}",
        "filepath": "test.yaml",
        "line": 7,
        "column": 23,
        "kind": "expression",
        "snippet": "      - run: echo ${{ runner.unknown_prop }}\n                      ^~~~~~~~~~~~~~~~~~~",
        "end_column": 41
      }
    ]
  • Overhaul the workflow parser to parse workflow keys in case-insensitive. This is a work derived from the fix of #216. Now the parser parses all workflow keys in case-insensitive way correctly. Note that permission names at permissions: are exceptionally case-sensitive.
    • This fixes properties of inputs for workflow_dispatch were not case-insensitive.
    • This fixes inputs and outputs of local actions were not handled in case-insensitive way.
  • Update popular actions data set. actions/stale@v6 was newly added.

Changes

v1.6.19 - 22 Sep 2022

  • Fix inputs, outputs, and secrets of reusable workflow should be case-insensitive. (#216)
    # .github/workflows/reusable.yaml
    on:
      workflow_call:
        inputs:
          INPUT_UPPER:
            type: string
          input_lower:
            type: string
        secrets:
          SECRET_UPPER:
          secret_lower:
    ...
    
    # .github/workflows/test.yaml
    ...
    
    jobs:
      caller:
        uses: ./.github/workflows/reusable.yaml
        # Inputs and secrets are case-insensitive. So all the followings should be OK
        with:
          input_upper: ...
          INPUT_LOWER: ...
        secrets:
          secret_upper: ...
          SECRET_LOWER: ...
  • Describe how to install specific version of actionlint binary with the download script. (#218)

Changes

v1.6.18 - 17 Sep 2022

  • This release much enhances checks for local reusable workflow calls. Note that these checks are done for local reusable workflows (starting with ./). (#179).
    • Detect missing required inputs/secrets and undefined inputs/secrets at jobs.<job_id>.with and jobs.<job_id>.secrets. See the document for more details.
      # .github/workflows/reusable.yml
      on:
        workflow_call:
          inputs:
            name:
              type: string
              required: true
          secrets:
            password:
              required: true
      ...
      
      # .github/workflows/test.yml
      ...
      
      jobs:
        missing-required:
          uses: ./.github/workflows/reusable.yml
          with:
            # ERROR: Undefined input "user"
            user: rhysd
            # ERROR: Required input "name" is missing
          secrets:
            # ERROR: Undefined secret "credentials"
            credentials: my-token
            # ERROR: Required secret "password" is missing
    • Type check for reusable workflow inputs at jobs.<job_id>.with. Types are defined at on.workflow_call.inputs.<name>.type in reusable workflow. actionlint checks types of expressions in workflow calls. See the document for more details.
      # .github/workflows/reusable.yml
      on:
        workflow_call:
          inputs:
            id:
              type: number
            message:
              type: string
      ...
      
      # .github/workflows/test.yml
      ...
      
      jobs:
        type-checks:
          uses: ./.github/workflows/reusable.yml
          with:
            # ERROR: Cannot assign string value to number input. format() returns string value
            id: ${{ format('runner name is {0}', runner.name) }}
            # ERROR: Cannot assign null to string input. If you want to pass string "null", use ${{ 'null' }}
            message: null
    • Detect local reusable workflow which does not exist at jobs.<job_id>.uses. See the document for more details.
      jobs:
        test:
          # ERROR: This workflow file does not exist
          with: ./.github/workflows/does-not-exist.yml
    • Check needs.<job_id>.outputs.<output_id> in downstream jobs of workflow call jobs. The outputs object is now typed strictly based on on.workflow_call.outputs.<name> in the called reusable workflow. See the document for more details.
      # .github/workflows/get-build-info.yml
      on:
        workflow_call:
          outputs:
            version:
              value: ...
              description: version of software
      ...
      
      # .github/workflows/test.yml
      ...
      
      jobs:
        # This job's outputs object is typed as {version: string}
        get_build_info:
          uses: ./.github/workflows/get-build-info.yml
        downstream:
          needs: [get_build_info]
          runs-on: ubuntu-latest
          steps:
            # OK. `version` is defined in the reusable workflow
            - run: echo '${{ needs.get_build_info.outputs.version }}'
            # ERROR: `tag` is not defined in the reusable workflow
            - run: echo '${{ needs.get_build_info.outputs.tag }}'
  • Add missing properties in contexts and improve types of some properties looking at the official contexts document.
    • github.action_status
    • runner.debug
    • services.<service_id>.ports
  • Fix on.workflow_call.inputs.<name>.description and on.workflow_call.secrets.<name>.description were incorrectly mandatory. They are actually optional.
  • Report parse errors when parsing action.yml in local actions. They were ignored in previous versions.
  • Sort the order of properties in an object type displayed in error message. In previous versions, actionlint sometimes displayed {a: true, b: string}, or it displayed {b: string, a: true} for the same object type. This randomness was caused by random iteration of map values in Go.
  • Update popular actions data set to the latest.

Changes

v1.6.17 - 28 Aug 2022

  • Allow workflow calls are available in matrix jobs. See the official announcement for more details. (#197)
    jobs:
      ReuseableMatrixJobForDeployment:
        strategy:
          matrix:
            target: [dev, stage, prod]
        uses: octocat/octo-repo/.github/workflows/deployment.yml@main
        with:
          target: ${{ matrix.target }}
  • Allow nested workflow calls. See the official announcement for more details. (#201)
    on: workflow_call
    
    jobs:
      call-another-reusable:
        uses: path/to/another-reusable.yml@v1
  • Fix job outputs should be passed to needs.*.outputs of only direct children. Until v1.6.16, they are passed to any downstream jobs. (#151)
    jobs:
      first:
        runs-on: ubuntu-latest
        outputs:
          first: 'output from first job'
        steps:
          - run: echo 'first'
    
      second:
        needs: [first]
        runs-on: ubuntu-latest
        outputs:
          second: 'output from second job'
        steps:
          - run: echo 'second'
    
      third:
        needs: [second]
        runs-on: ubuntu-latest
        steps:
          - run: echo '${{ toJSON(needs.second.outputs) }}'
          # ERROR: `needs.first` does not exist, but v1.6.16 reported no error
          - run: echo '${{ toJSON(needs.first.outputs) }}'
    When you need both needs.first and needs.second, add the both to needs:.
      third:
        needs: [first, second]
        runs-on: ubuntu-latest
        steps:
          # OK
          -  echo '${{ toJSON(needs.first.outputs) }}'
  • Fix }} in string literals are detected as end marker of placeholder ${{ }}. (#205)
    jobs:
      test:
        runs-on: ubuntu-latest
        strategy:
          # This caused an incorrect error until v1.6.16
          matrix: ${{ fromJSON('{"foo":{}}') }}
  • Fix working-directory: should not be available with uses: in steps. working-directory: is only available with run:. (#207)
    steps:
      - uses: actions/checkout@v3
        # ERROR: `working-directory:` is not available here
        working-directory: ./foo
  • The working directory for running actionlint command can be set via WorkingDir field of LinterOptions struct. When it is empty, the return value from os.Getwd will be used.
  • Update popular actions data set. actions/configure-pages@v2 was added.
  • Use Go 1.19 on CI by default. It is used to build release binaries.
  • Update dependencies (go-yaml/yaml v3.0.1).
  • Update playground dependencies (except for CodeMirror v6).

Changes

v1.6.16 - 19 Aug 2022

  • Allow an empty object at permissions:. You can use it to disable permissions for all of the available scopes. (#170, #171, thanks @peaceiris)
    permissions: {}
  • Support github.triggering_actor context value. (#190, thanks @stefreak)
  • Rename step-id rule to id rule. Now the rule checks both job IDs and step IDs. See the document for more details. (#182)
    jobs:
      # ERROR: '.' cannot be contained in ID
      v1.2.3:
        runs-on: ubuntu-latest
        steps:
          - run: echo 'job ID with version'
            # ERROR: ID cannot contain spaces
            id: echo for test
      # ERROR: ID cannot start with numbers
      2d-game:
        runs-on: ubuntu-latest
        steps:
          - run: echo 'oops'
  • Accessing env context in jobs.<id>.if is now reported as error. (#155)
    jobs:
      test:
        runs-on: ubuntu-latest
        # ERROR: `env` is not available here
        if: ${{ env.DIST == 'arch' }}
        steps:
          - run: ...
  • Fix actionlint wrongly typed some matrix value when the matrix is expanded with ${{ }}. For example, matrix.foo in the following code is typed as {x: string}, but it should be any because it is initialized with the value from fromJSON. (#145)
    strategy:
      matrix:
        foo: ${{ fromJSON(...) }}
        exclude:
          - foo:
              x: y
  • Fix incorrect type check when multiple runner labels are set to runs-on: via expanding ${{ }} for selecting self-hosted runners. (#164)
    jobs:
      test:
        strategy:
          matrix:
            include:
              - labels: ["self-hosted", "macOS", "X64"]
              - labels: ["self-hosted", "linux"]
        # actionlint incorrectly reported type error here
        runs-on: ${{ matrix.labels }}
  • Fix usage of local actions (uses: ./path/to/action) was not checked when multiple workflow files were passed to actionlint command. (#173)
  • Allow description: is missing in secrets: of reusable workflow call definition since it is optional. (#174)
  • Fix type of propery of github.event.inputs is string unlike inputs context. See the document for more details. (#181)
    on:
      workflow_dispatch:
        inputs:
          is-valid:
            # Type of `inputs.is-valid` is bool
            # Type of `github.event.inputs.is-valid` is string
            type: boolean
  • Fix crash when a value is expanded with ${{ }} at continue-on-error:. (#193)
  • Fix some error was caused by some other error. For example, the following code reported two errors. '" is not available for string literal' error caused another 'one placeholder should be included in boolean value string' error. This was caused because the ${{ x == "foo" }} placeholder was not counted due to the previous type error.
    if: ${{ x == "foo" }}
  • Add support for merge_group workflow trigger.
  • Add official actions to manage GitHub Pages to popular actions data set.
    • actions/configure-pages@v1
    • actions/deploy-pages@v1
    • actions/upload-pages-artifact@v1
  • Update popular actions data set to the latest. Several new major versions and new inputs of actions were added to it.
  • Describe how to install actionlint via Chocolatey, scoop, and AUR in the installation document. (#167, #168, thanks @sitiom)
  • VS Code extension for actionlint was created by @arahatashun. See the document for more details.
  • Describe how to use the Docker image at step of GitHub Actions workflow. See the document for the details. (#146)
    - uses: docker://rhysd/actionlint:latest
      with:
        args: -color
  • Clarify the behavior if empty strings are set to some command line options in documents. -shellcheck= disables shellcheck integration and -pyflakes= disables pyflakes integration. (#156)
  • Update Go module dependencies.

Changes

v1.6.15 - 28 Jun 2022

  • Fix referring env context from env: at step level caused an error. env: at toplevel and job level cannot refer env context, but env: at step level can. (#158)
    on: push
    
    env:
      # ERROR: 'env:' at toplevel cannot refer 'env' context
      ERROR1: ${{ env.PATH }}
    
    jobs:
      my_job:
        runs-on: ubuntu-latest
        env:
          # ERROR: 'env:' at job level cannot refer 'env' context
          ERROR2: ${{ env.PATH }}
        steps:
          - run: echo "$THIS_IS_OK"
            env:
              # OK: 'env:' at step level CAN refer 'env' context
              THIS_IS_OK: ${{ env.PATH }}
  • Docker image for linux/arm64 is now provided. It is useful for M1 Mac users. (#159, thanks @politician)
  • Fix the download script did not respect the version specified via the first argument. (#162, thanks @mateiidavid)

Changes

v1.6.14 - 26 Jun 2022

  • Some filters are exclusive in events at on:. Now actionlint checks the exclusive filters are used in the same event. paths and paths-ignore, branches and branches-ignore, tags and tags-ignore are exclusive. See the document for the details.
    on:
      push:
        # ERROR: Both 'paths' and 'paths-ignore' filters cannot be used for the same event
        paths: ...
        paths-ignore: ...
  • Some event filters are checked more strictly. Some filters are only available with specific events. Now actionlint checks the limitation. See the document for complete list of such filters.
    on:
      release:
        # ERROR: 'tags' filter is only available for 'push' event
        tags: v*.*.*
  • Paths starting/ending with spaces are now reported as error.
  • Inputs of workflow which specify both default and required are now reported as error. When required is specified at input of workflow call, a caller of it must specify value of the input. So the default value will never be used. (#154, thanks @sksat)
    on:
      workflow_call:
        inputs:
          my_input:
            description: test
            type: string
            # ERROR: The default value 'aaa' will never be used
            required: true
            default: aaa
  • Fix inputs of workflow_dispatch are set to inputs context as well as github.event.inputs. This was added by the recent change of GitHub Actions. (#152)
    on:
      workflow_dispatch:
        inputs:
          my_input:
            type: string
            required: true
    jobs:
      my_job:
        runs-on: ubuntu-latest
        steps:
          - run: echo ${{ github.event.inputs.my_input }}
          # Now the input is also set to `inputs` context
          - run: echo ${{ inputs.my_input }}
  • Improve that env context is now not defined in values of env:, id: and uses:. actionlint now reports usage of env context in such places as type errors. (#158)
    runs-on: ubuntu-latest
    env:
      FOO: aaa
    steps:
      # ERROR: 'env' context is not defined in values of 'env:', 'id:' and 'uses:'
      - uses: test/${{ env.FOO }}@main
        env:
          BAR: ${{ env.FOO }}
        id: foo-${{ env.FOO }}
  • actionlint command gains -stdin-filename command line option. When it is specified, the file name is used on reading input from stdin instead of <stdin>. (#157, thanks @arahatashun)
    # Error message shows foo.yml as file name where the error happened
    ... | actionlint -stdin-filename foo.yml -
  • The download script allows to specify a directory path to install actionlint executable with the second argument of the script. For example, the following command downloads /path/to/bin/actionlint:
    # Downloads the latest stable version at `/path/to/bin/actionlint`
    bash <(curl https://raw.githubusercontent.com/rhysd/actionlint/main/scripts/download-actionlint.bash) latest /path/to/bin
    # Downloads actionlint v1.6.14 at `/path/to/bin/actionlint`
    bash <(curl https://raw.githubusercontent.com/rhysd/actionlint/main/scripts/download-actionlint.bash) 1.6.14 /path/to/bin
  • Update popular actions data set including goreleaser-action@v3, setup-python@v4, aks-set-context@v3.
  • Update Go dependencies including go-yaml/yaml v3.

Changes

v1.6.13 - 18 May 2022

  • secrets: inherit in reusable workflow is now supported (#138)
    on:
      workflow_dispatch:
    
    jobs:
      pass-secrets-to-workflow:
        uses: ./.github/workflows/called-workflow.yml
        secrets: inherit
    This means that actionlint cannot know the workflow inherits secrets or not when checking a reusable workflow. To support secrets: inherit without giving up on checking secrets context, actionlint assumes the followings. See the document for the details.
    • when secrets: is omitted in a reusable workflow, the workflow inherits secrets from a caller
    • when secrets: exists in a reusable workflow, the workflow inherits no other secret
  • macos-12 runner is now supported (#134, thanks @shogo82148)
  • ubuntu-22.04 runner is now supported (#142, thanks @shogo82148)
  • concurrency is available on reusable workflow call (#136)
    jobs:
      checks:
        concurrency:
          group: ${{ github.ref }}-${{ github.workflow }}
          cancel-in-progress: true
        uses: ./path/to/workflow.yaml
  • pre-commit hook now uses a fixed version of actionlint. For example, the following configuration continues to use actionlint v1.6.13 even if v1.6.14 is released. (#116)
    repos:
      - repo: https://github.com/rhysd/actionlint
        rev: v1.6.13
        hooks:
          - id: actionlint-docker
  • Update popular actions data set including new versions of docker/*, haskell/actions/setup, actions/setup-go, ... (#140, thanks @bflad)
  • Update Go module dependencies

Changes

v1.6.12 - 14 Apr 2022

  • Fix secrets.ACTIONS_RUNNER_DEBUG and secrets.ACTIONS_STEP_DEBUG are not pre-defined in a reusable workflow. (#130)
  • Fix checking permissions is outdated. pages and discussions permissions were added and metadata permission was removed. (#131, thanks @suzuki-shunsuke)
  • Disable SC2157 shellcheck rule to avoid a false positive due to the replacement of ${{ }} in script. For example, in the below script -z ${{ env.FOO }} was replaced with -z ______________ and it caused 'always false due to literal strings' error. (#113)
    - run: |
        if [[ -z ${{ env.FOO }} ]]; then
          echo "FOO is empty"
        fi
  • Add codecov-action@v3 to popular actions data set.

Changes

v1.6.11 - 05 Apr 2022

  • Fix crash on making outputs in JSON format with actionlint -format '{{json .}}'. (#128)
  • Allow any outputs from actions/github-script action because it allows to set arbitrary outputs via calling core.setOutput() in JavaScript. (#104)
    - id: test
      uses: actions/github-script@v5
      with:
        script: |
          core.setOutput('answer', 42);
    - run: |
        echo "The answer is ${{ steps.test.outputs.answer }}"
  • Add support for Go 1.18. All released binaries were built with Go 1.18 compiler. The bottom supported version is Go 1.16 and it's not been changed.
  • Update popular actions data set (actions/cache, code-ql-actions/*, ...)
  • Update some Go module dependencies

Changes

v1.6.10 - 11 Mar 2022

  • Support outputs in reusable workflow call. See the official document for the usage of the outputs syntax. (#119, #121) Example of reusable workflow definition:
    on:
      workflow_call:
        outputs:
          some_output:
            description: "Some awesome output"
            value: 'result value of workflow call'
    jobs:
      job:
        runs-on: ubuntu-latest
        steps:
          ...
    Example of reusable workflow call:
    jobs:
      job1:
        uses: ./.github/workflows/some_workflow.yml
      job2:
        runs-on: ubuntu-latest
        needs: job1
        steps:
          - run: echo ${{ needs.job1.outputs.some_output }}
  • Support checking jobs context, which is only available in on.workflow_call.outputs.<name>.value. Outputs of jobs can be referred via the context. See the document for more details.
    on:
      workflow_call:
        outputs:
          image-version:
            description: "Docker image version"
            # ERROR: 'imagetag' does not exist (typo of 'image_tag')
            value: ${{ jobs.gen-image-version.outputs.imagetag }}
    jobs:
      gen-image-version:
        runs-on: ubuntu-latest
        outputs:
          image_tag: "${{ steps.get_tag.outputs.tag }}"
        steps:
          - run: ./output_image_tag.sh
            id: get_tag
  • Add new major releases in actions/* actions including actions/checkout@v3, actions/setup-go@v3, actions/setup-python@v3, ...
  • Check job IDs. They must start with a letter or _ and contain only alphanumeric characters, - or _. See the document for more details. (#80)
    on: push
    jobs:
      # ERROR: '.' cannot be contained in job ID
      foo-v1.2.3:
        runs-on: ubuntu-latest
        steps:
          - run: 'job ID with version'
  • Fix windows-latest now means windows-2022 runner. See virtual-environments#4856 for the details. (#120)
  • Update the playground dependencies to the latest.
  • Update Go module dependencies

Changes

v1.6.9 - 24 Feb 2022

  • Support runner.arch context value. (thanks @shogo82148, #101)
    steps:
      - run: ./do_something_64bit.sh
        if: ${{ runner.arch == 'x64' }}
  • Support calling reusable workflows in local directories. (thanks @jsok, #107)
    jobs:
      call-workflow-in-local-repo:
        uses: ./.github/workflows/useful_workflow.yml
  • Add a document to install actionlint via asdf version manager. (thanks @crazy-matt, #99)
  • Fix using secrets.GITHUB_TOKEN caused a type error when some other secret is defined. (thanks @mkj-is, #106)
  • Fix nil check is missing on parsing uses: step. (thanks @shogo82148, #102)
  • Fix some documents including broken links. (thanks @ohkinozomu, #105)
  • Update popular actions data set to the latest. More arguments are added to many actions. And a few actions had new major versions.
  • Update webhook payload data set to the latest. requested_action type was added to check_run hook. requested and rerequested types were removed from check_suite hook. updated type was removed from project hook.

Changes

v1.6.8 - 15 Nov 2021

  • Untrusted inputs detection can detect untrusted inputs in object filter syntax. For example, github.event.*.body filters body properties and it includes the untrusted input github.event.comment.body. actionlint detects such filters and causes an error. The error message includes all untrusted input names which are filtered by the object filter so that you can know what inputs are untrusted easily. See the document for more details. Input example:
    - name: Get comments
      run: echo '${{ toJSON(github.event.*.body) }}'
    Error message:
    object filter extracts potentially untrusted properties "github.event.comment.body", "github.event.discussion.body", "github.event.issue.body", ...
    
    Instead you should do:
    - name: Get comments
      run: echo "$JSON"
      env:
        JSON: {{ toJSON(github.event.*.body) }}
  • Support the new input type syntax for workflow_dispatch event, which was introduced recently. You can declare types of inputs on triggering a workflow manually. actionlint does two things with this new syntax.
    • actionlint checks the syntax. Unknown input types, invalid default values, missing options for 'choice' type.
      inputs:
        # Unknown input type
        id:
          type: number
        # ERROR: No options for 'choice' input type
        kind:
          type: choice
        name:
          type: choice
          options:
            - Tama
            - Mike
          # ERROR: Default value is not in options
          default: Chobi
        verbose:
          type: boolean
          # ERROR: Boolean value must be 'true' or 'false'
          default: yes
    • actionlint give a strict object type to github.event.inputs so that a type checker can check unknown input names and type mismatches on using the value.
      on:
        workflow_dispatch:
          inputs:
            message:
              type: string
            verbose:
              type: boolean
      # Type of `github.event.inputs` is {"message": string; "verbose": bool}
      jobs:
        test:
          runs-on: ubuntu-latest
          steps:
            # ERROR: Undefined input
            - run: echo "${{ github.event.inputs.massage }}"
            # ERROR: Bool value is not available for object key
            - run: echo "${{ env[github.event.inputs.verbose] }}"
    • See the document for more details.
  • Add missing properties in github context. See the contexts document to know the full list of properties.
    • github.ref_name (thanks @dihmandrake, #72)
    • github.ref_protected
    • github.ref_type
  • Filtered array by object filters is typed more strictly.
    # `env` is a map object { string => string }
    # Previously typed as array<any> now it is typed as array<string>
    env.*
    
  • Update Go module dependencies and playground dependencies.

Changes

v1.6.7 - 08 Nov 2021

  • Fix missing property name in runner context object (thanks @ioanrogers, #67).
  • Fix a false positive on type checking at x.* object filtering syntax where the receiver is an object. actionlint previously only allowed arrays as receiver of object filtering (#66).
    fromJSON('{"a": "from a", "b": "from b"}').*
    # => ["from a", "from b"]
    
    fromJSON('{"a": {"x": "from a.x"}, "b": {"x": "from b.x"}}').*.x
    # => ["from a.x", "from b.x"]
  • Add rust-cache as new popular action.
  • Remove bottle: unneeded from Homebrew formula (thanks @oppara, #63).
  • Support branch_protection_rule webhook again.
  • Update popular actions data set to the latest (#64, #70).

Changes

v1.6.6 - 17 Oct 2021

  • inputs and secrets objects are now typed looking at workflow_call event at on:. See the document for more details.
    • inputs object is typed with definitions at on.workflow_call.inputs. When the workflow is not callable, it is typed at {} (empty object) so any inputs.* access causes a type error.
    • secrets object is typed with definitions at on.workflow_call.secrets.
    on:
      workflow_call:
        # `inputs` object is typed {url: string; lucky_number: number}
        inputs:
          url:
            description: 'your URL'
            type: string
          lucky_number:
            description: 'your lucky number'
            type: number
        # `secrets` object is typed {user: string; credential: string}
        secrets:
          user:
            description: 'your user name'
          credential:
            description: 'your credential'
    jobs:
      test:
        runs-on: ubuntu-20.04
        steps:
          - name: Send data
            # ERROR: uri is typo of url
            run: curl ${{ inputs.uri }} -d ${{ inputs.lucky_number }}
            env:
              # ERROR: credentials is typo of credential
              TOKEN: ${{ secrets.credentials }}
  • id-token is added to permissions (thanks @cmmarslender, #62).
  • Report an error on nested workflow calls since it is not allowed.
    on:
      # This workflow is reusable
      workflow_call:
    
    jobs:
      test:
        # ERROR: Nested workflow call is not allowed
        uses: owner/repo/path/to/workflow.yml@ref
  • Parse uses: at reusable workflow call more strictly following {owner}/{repo}/{path}@{ref} format.
  • Popular actions data set was updated to the latest (#61).
  • Dependencies of playground were updated to the latest (including eslint v8).

Changes

v1.6.5 - 08 Oct 2021

  • Support reusable workflows syntax which is now in beta. Only very basic syntax checks are supported at this time. Please see the document to know checks for reusable workflow syntax.
    • Example of workflow_call event
      on:
        workflow_call:
          inputs:
            name:
              description: your name
              type: string
          secrets:
            token:
              required: true
      
      jobs:
        ...
    • Example of reusable workflow call with uses: at job.<job_id>
      on: ...
      jobs:
        hello:
          uses: owner/repo/path/to/workflow.yml@main
          with:
            name: Octocat
          secrets:
            token: ${{ secrets.token }}
  • Support github.run_attempt property in ${{ }} expression (#57).
  • Add support for windows-2022 runner which is now in public beta.
  • Remove support for ubuntu-16.04 runner which was removed from GitHub Actions at the end of September.
  • Ignore SC2154 shellcheck rule which can cause false positive (#53).
  • Fix error position was not correct when required keys are not existing in job configuration.
  • Update popular actions data set. New major versions of github-script and lock-threads actions are supported (#59).
  • Fix document (thanks @fornwall at #52, thanks @equal-l2 at #56).

Changes

v1.6.4 - 21 Sep 2021

  • Implement 'map' object types { string => T }, where all properties of the object are typed as T. Since a key of object is always string, left hand side of => is fixed to string. For example, env context only has string properties so it is typed as { string => string}. Previously its properties were typed any.
    # typed as string (previously any)
    env.FOO
    
    # typed as { id: string; network: string; ports: object; } (previously any)
    job.services.redis
  • github.event.discussion.title and github.event.discussion.body are now checked as untrusted inputs.
  • Update popular actions data set. (#50, #51)
  • Update webhooks payload data set. branch_protection_rule hook was dropped from the list due to github/docs@179a6d3. (#50, #51)

Changes

v1.6.3 - 04 Sep 2021

  • Improve guessing a type of matrix value. When a matrix contains numbers and strings, previously the type fell back to any. Now it is deduced as string.
    strategy:
      matrix:
        # matrix.node is now deduced as `string` instead of `any`
        node: [14, 'latest']
  • Fix types of || and && expressions. Previously they were typed as bool but it was not correct. Correct type is sum of types of both sides of the operator like TypeScript. For example, type of 'foo' || 'bar' is a string, and github.event && matrix is an object.
  • actionlint no longer reports an error when a local action does not exist in the repository. It is a popular pattern that a local action directory is cloned while a workflow running. (#25, #40)
  • Disable SC2050 shellcheck rule since it causes some false positive. (#45)
  • Fix -version did not work when running actionlint via the Docker image (#47).
  • Fix pre-commit hook file name. (thanks @xsc27, #38)
  • New branch_protection_rule event is supported. (#48)
  • Update popular actions data set. (#41, #48)
  • Update Go library dependencies.
  • Update playground dependencies.

Changes

v1.6.2 - 23 Aug 2021

  • actionlint now checks evaluated values at ${{ }} are not an object nor an array since they are not useful. See the check document for more details.
# ERROR: This will always be replaced with `echo 'Object'`
- run: echo '${{ runner }}'
# OK: Serialize an object into JSON to check the content
- run: echo '${{ toJSON(runner) }}'
docker run --rm -v $(pwd):/repo --workdir /repo rhysd/actionlint:latest -color
  • Go 1.17 is now a default compiler to build actionlint. Built binaries are faster than before by 2~7% when the process is CPU-bound. Sizes of built binaries are about 2% smaller. Note that Go 1.16 continues to be supported.
  • windows/arm64 target is added to released binaries thanks to Go 1.17.
  • Now any value can be converted into bool implicitly. Previously this was not permitted as actionlint provides stricter type check. However it is not useful that a condition like if: github.event.foo causes a type error.
  • Fix a prefix operator cannot be applied repeatedly like !!42.
  • Fix a potential crash when type checking on expanding an object with ${{ }} like matrix: ${{ fromJSON(env.FOO) }}
  • Update popular actions data set (#36)

Changes

v1.6.1 - 16 Aug 2021

annotation by Problem Matchers

  • runner_label rule now checks conflicts in labels at runs-on. For example, there is no runner which meats both ubuntu-latest and windows-latest. This kind of misconfiguration sometimes happen when a beginner misunderstands the usage of runs-on:. To run a job on each runners, matrix: should be used. See the document for more information.
on: push
jobs:
  test:
    # These labels match to no runner
    runs-on: [ubuntu-latest, windows-latest]
    steps:
      - run: echo ...
  • Reduce memory footprint (around 16%) on starting actionlint command by removing unnecessary data from PopularActions global variable. This also slightly reduces binary size (about 3.7% at playground/main.wasm).
  • Fix accessing steps.* objects in job's environment: configuration caused a type error (#30).
  • Fix checking that action's input names at with: were not in case insensitive (#31).
  • Ignore outputs of getsentry/paths-filter. It is a fork of dorny/paths-filter. actionlint cannot check the outputs statically because it sets outputs dynamically.
  • Add Azure/functions-action to popular actions.
  • Update popular actions data set (#29).

Changes

v1.6.0 - 11 Aug 2021

Incorrect code

- run: echo '${{ github.event.pull_request.title }}'

should be replaced with

- run: echo "issue ${TITLE}"
  env:
    TITLE: ${{github.event.issue.title}}

Simple example to output error messages as JSON:

actionlint -format '{{json .}}'

More compliated example to output error messages as markdown:

actionlint -format '{{range $ := .}}### Error at line {{$.Line}}, col {{$.Column}} of `{{$.Filepath}}`\n\n{{$.Message}}\n\n```\n{{$.Snippet}}\n```\n\n{{end}}'
  • Documents are reorganized. Long README.md is separated into several document files (#28)
  • Fix checking shell names was not case-insensitive, for example PowerShell was detected as invalid shell name
  • Update popular actions data set to the latest
  • Make lexer errors on checking ${{ }} expressions more meaningful

Changes

v1.5.3 - 04 Aug 2021

  • Now actionlint allows to use any operators outside ${{ }} on if: condition like if: github.repository_owner == 'rhysd' (#22). The official document said that using any operator outside ${{ }} was invalid even if it was on if: condition. However, github/docs#8786 clarified that the document was not correct.

Changes

v1.5.2 - 02 Aug 2021

  • Outputs of dorny/paths-filter are now not typed strictly because the action dynamically sets outputs which are not defined in its action.yml. actionlint cannot check such outputs statically (#18).
  • The table for checking Webhooks supported by GitHub Actions is now generated from the official document automatically with script. The table continues to be updated weekly by the CI workflow.
  • Improve error messages while lexing expressions as follows.
  • Fix column numbers are off-by-one on some lexer errors.
  • Fix checking invalid numbers where some digit follows zero in a hex number (e.g. 0x01) or an exponent part of number (e.g. 1e0123).
  • Fix a parse error message when some tokens still remain after parsing finishes.
  • Refactor the expression lexer to lex an input incrementally. It slightly reduces memory consumption.

Lex error until v1.5.1:

test.yaml:9:26: got unexpected character '+' while lexing expression, expecting '_', '\'', '}', '(', ')', '[', ']', '.', '!', '<', '>', '=', '&', '|', '*', ',', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' [expression]

Lex error from v1.5.2:

test.yaml:9:26: got unexpected character '+' while lexing expression, expecting 'a'..'z', 'A'..'Z', '0'..'9', ''', '}', '(', ')', '[', ']', '.', '!', '<', '>', '=', '&', '|', '*', ',', '_' [expression]

Changes

v1.5.1 - 29 Jul 2021

  • Improve checking the intervals of scheduled events (#14, #15). Since GitHub Actions limits the interval to once every 5 minutes, actionlint now reports an error when a workflow is configured to be run once per less than 5 minutes.
  • Skip checking inputs of octokit/request-action since it allows to specify arbitrary inputs though they are not defined in its action.yml (#16).
    • Outputs of the action are still be typed strictly. Only its inputs are not checked.
  • The help text of actionlint is now hosted online: https://rhysd.github.io/actionlint/usage.html
  • Add new fuzzing target for parsing glob patterns.

Changes

v1.5.0 - 26 Jul 2021

  • action rule now validates inputs of popular actions at with:. When a required input is not specified or an undefined input is specified, actionlint will report it.
    • Popular actions are updated automatically once a week and the data set is embedded to executable directly. The check does not need any network request and does not affect performance of actionlint. Sources of the actions are listed here. If you have some request to support new action, please report it at the issue form.
    • Please see the document for example (Playground).
  • expression rule now types outputs of popular actions (type of steps.{id}.outputs object) more strictly.
    • For example, actions/cache@v2 sets cache-hit output. The outputs object is typed as { cache-hit: any }. Previously it was typed as any which means no further type check was performed.
    • Please see the second example of the document (Playground).
  • Outputs of local actions (their names start with ./) are also typed more strictly as well as popular actions.
  • Metadata (action.yml) of local actions are now cached to avoid reading and parsing action.yml files repeatedly for the same action.
  • Add new rule permissions to check permission scopes for default secrets.GITHUB_TOKEN. Please see the document for more details (Playground).
  • Structure of actionlint.Permissions struct was changed. A parser no longer checks values of permissions: configuration. The check is now done by permissions rule.

Changes

v1.4.3 - 21 Jul 2021

  • Support new Webhook events discussion and discussion_comment (#8).
  • Read file concurrently with limiting concurrency to number of CPUs. This improves performance when checking many files and disabling shellcheck/pyflakes integration.
  • Support Linux based on musl libc by the download script (#5).
  • Reduce number of goroutines created while running shellcheck/pyflakes processes. This has small impact on memory usage when your workflows have many run: steps.
  • Reduce built binary size by splitting an external library which is only used for debugging into a separate command line tool.
  • Introduce several micro benchmark suites to track performance.
  • Enable code scanning for Go/TypeScript/JavaScript sources in actionlint repository.

Changes

v1.4.2 - 16 Jul 2021

  • Fix executables in the current directory may be used unexpectedly to run shellcheck or pyflakes on Windows. This behavior could be security vulnerability since an attacker might put malicious executables in shared directories. actionlint searched an executable with exec.LookPath, but it searched the current directory on Windows as golang/go#43724 pointed. Now actionlint uses execabs.LookPath instead, which does not have the issue. (ref: sharkdp/bat#1724)
  • Fix issue caused by running so many processes concurrently. Since checking workflows by actionlint is highly parallelized, checking many workflow files makes too many shellcheck processes and opens many files in parallel. This hit OS resources limitation (issue #3). Now reading files is serialized and number of processes run concurrently is limited for fixing the issue. Note that checking workflows is still done in parallel so this fix does not affect actionlint's performance.
  • Ensure cleanup processes even if actionlint stops due to some fatal issue while visiting a workflow tree.
  • Improve fatal error message to know which workflow file caused the error.
  • Playground improvements

Changes

v1.4.1 - 12 Jul 2021

  • A pre-built executable for darwin/arm64 (Apple M1) was added to CI (#1)
    • Managing actionlint command with Homebrew on M1 Mac is now available. See the instruction for more details
    • Since the author doesn't have M1 Mac and GitHub Actions does not support M1 Mac yet, the built binary is not tested
  • Pre-built executables are now built with Go 1.16 compiler (previously it was 1.15)
  • Fix error message is sometimes not in one line when the error message was caused by go-yaml/yaml parser
  • Fix playground does not work on Safari browsers on both iOS and Mac since they don't support WebAssembly.instantiateStreaming() yet
  • Make URLs in error messages clickable on playground
  • Code base of playground was migrated from JavaScript to Typescript along with improving error handlings

Changes

v1.4.0 - 09 Jul 2021

  • New rule to validate glob pattern syntax to filter branches, tags and paths. For more details, see documentation.
    • syntax errors like missing closing brackets for character range [..]
    • invalid usage like ? following *, invalid character range [9-1], ...
    • invalid character usage for Git ref names (branch name, tag name)
      • ref name cannot start/end with /
      • ref name cannot contain [, :, \, ...
  • Fix column of error position is off by one when the error is caused by quoted strings like '...' or "...".
  • Add --norc option to shellcheck command to check shell scripts in run: in order not to be affected by any user configuration.
  • Improve some error messages
  • Explain playground in man manual

Changes

v1.3.2 - 04 Jul 2021

  • actionlint playground was implemented thanks to WebAssembly. actionlint is now available on browser without installing anything. The playground does not send user's workflow content to any remote server.
  • Some margins are added to code snippets in error message. See below examples. I believe it's easier to recognize code in bunch of error messages than before.
  • Line number is parsed from YAML syntax error. Since errors from go-yaml/go don't have position information, previously YAML syntax errors are reported at line:0, col:0. Now line number is parsed from error message and set correctly (if error message includes line number).
  • Code snippet is shown in error message even if column number of the error position is unknown.
  • Fix error message on detecting duplicate of step IDs.
  • Fix and improve validating arguments of format() calls.
  • All rule documents have links to actionlint playground with example code.
  • man manual covers usage of actionlint on CI services.

Error message until v1.3.1:

test.yaml:4:13: invalid CRON format "0 */3 * *" in schedule event: Expected exactly 5 fields, found 4: 0 */3 * * [events]
4|     - cron: '0 */3 * *'
 |             ^~

Error message at v1.3.2:

test.yaml:4:13: invalid CRON format "0 */3 * *" in schedule event: Expected exactly 5 fields, found 4: 0 */3 * * [events]
  |
4 |     - cron: '0 */3 * *'
  |             ^~

Changes

v1.3.1 - 30 Jun 2021

  • Files are checked in parallel. This made actionlint around 1.3x faster with 3 workflow files in my environment
  • Manual for man command was added. actionlint.1 is included in released archives. If you installed actionlint via Homebrew, the manual is also installed automatically
  • -version now reports how the binary was built (Go version, arch, os, ...)
  • Added Command struct to manage entire command lifecycle
  • Order of checked files is now stable. When all the workflows in the current repository are checked, the order is sorted by file names
  • Added fuzz target for rule checkers

Changes

v1.3.0 - 26 Jun 2021

  • -version now outputs how the executable was installed.
  • Fix errors output to stdout was not colorful on Windows.
  • Add new -color flag to force to enable colorful outputs. This is useful when running actionlint on GitHub Actions since scripts at run: don't enable colors.
  • Linter.LintFiles and Linter.LintFile methods take project parameter to explicitly specify what project the files belong to. Leaving it nil automatically detects projects from their file paths.
  • LintOptions.NoColor is replaced by LintOptions.Color.

Example of -version output:

$ brew install actionlint
$ actionlint -version
1.3.0
downloaded from release page

$ go install github.com/rhysd/actionlint/cmd/actionlint@v1.3.0
go: downloading github.com/rhysd/actionlint v1.3.0
$ actionlint -version
v1.3.0
built from source

Example of running actionlint on GitHub Actions forcing to enable color output:

- name: Check workflow files
  run: |
    bash <(curl https://raw.githubusercontent.com/rhysd/actionlint/main/scripts/download-actionlint.bash)
    ./actionlint -color
  shell: bash

Changes

v1.2.0 - 25 Jun 2021

  • pyflakes integration was added. If pyflakes is installed on your system, actionlint checks Python scripts in run: (when shell: python) with it. See the rule document for more details.
  • Error handling while running rule checkers was improved. When some internal error occurs while applying rules, actionlint stops correctly due to the error. Previously, such errors were only shown in debug logs and actionlint continued checks.
  • Fixed sanitizing ${{ }} expressions in scripts before passing them to shellcheck or pyflakes. Previously expressions were not correctly sanitized when }} came before ${{.

Changes

v1.1.2 - 21 Jun 2021

  • Run shellcheck command for scripts at run: in parallel. Since executing an external process is heavy and running shellcheck was bottleneck of actionlint, this brought better performance. In my environment, it was more than 3x faster than before.
  • Sort errors by their positions in the source file.

Changes

v1.1.1 - 20 Jun 2021

  • download-actionlint.yaml now sets executable output when it is run in GitHub Actions environment. Please see instruction in 'Install' document for the usage.
  • Redundant type ArrayDerefType was removed. Instead, Deref field is now provided in ArrayType.
  • Fix crash on broken YAML input.
  • actionlint -version returns correct version string even if the actionlint command was installed via go install.

Changes

v1.1.0 - 19 Jun 2021

  • Ignore SC1091 and SC2194 on running shellcheck. These are reported as false positives due to sanitization of ${{ ... }}. See the check doc to know the sanitization.
  • actionlint replaces ${{ }} in run: scripts before passing them to shellcheck. v1.0.0 replaced ${{ }} with whitespaces, but it caused syntax errors in some scripts (e.g. if ${{ ... }}; then ...). Instead, v1.1.0 replaces ${{ }} with underscores. For example, ${{ matrix.os }} is replaced with ________________.
  • Add download-actionlint.bash script to download pre-built binaries easily on CI services. See installation document for the usage.
  • Better error message on lexing " in ${{ }} expression since double quote is usually misused for string delimiters
  • -ignore option can now be specified multiple times.
  • Fix github.repositoryUrl was not correctly resolved in ${{ }} expression
  • Reports an error when if: condition does not use ${{ }} but the expression contains any operators. The official document prohibits this explicitly to avoid conflicts with YAML syntax.
  • Clarify that the version of this repository is for actionlint CLI tool, not for library. It means that the APIs may have breaking changes on minor or patch version bumps.
  • Add more tests and refactor some code. Enumerating quoted items in error message is now done more efficiently and in deterministic order.

Changes

v1.0.0 - 16 Jun 2021

First release 🎉

See documentation for more details:

Changes