Skip to content

False positives for container.credentials and YAML anchors when values are built with expressions #590

@neilime

Description

@neilime

Hi, here is an issue I have with credentials entry lint:

Summary

actionlint 1.7.8 reports multiple syntax errors when a job’s container definition is driven entirely by expressions and then re-used via a YAML anchor. The workflow dynamically builds the credentials object with fromJSON(...) so that we can omit credentials when a private registry is not required. GitHub Actions accepts this template, but actionlint assumes the node must be a static mapping and raises syntax errors.

Environment

  • actionlint v1.7.8 (docker image rhysd/actionlint:1.7.8)
  • Workflow platform: GitHub Actions reusable workflow
  • The errors reproduce both inside Super-Linter (which embeds actionlint 1.7.8) and when running the container locally.

Minimal workflow excerpt

jobs:
  prepare:
    outputs:
      container-image: ${{ steps.parse.outputs.container-image }}
      container-options: ${{ steps.parse.outputs.container-options }}
      container-username: ${{ steps.parse.outputs.container-username }}
    # …parsing logic omitted for brevity…

  setup:
    runs-on: ubuntu-latest
    needs: prepare
    container: &container-setup
      image: ${{ needs.prepare.outputs.container-image || '' }}
      options: ${{ needs.prepare.outputs.container-options || ' ' }}
      credentials: ${{ fromJSON(
        needs.prepare.outputs.container-username &&
        format(
          '{{"username":{0},"password":{1}}}',
          toJSON(needs.prepare.outputs.container-username),
          toJSON(secrets.container-password)
        ) || '{}'
      ) }}
    steps:
      - run: echo "setup"

  lint:
    runs-on: ubuntu-latest
    needs: [prepare, setup]
    container: *container-setup
    steps:
      - run: echo "lint"

Steps to Reproduce

  1. Save the snippet above into .github/workflows/repro.yml.
  2. Execute actionlint against the file (directly from the official container):
    docker run --rm -v "$PWD":/repo --workdir /repo rhysd/actionlint:1.7.8 .github/workflows/repro.yml

Actual Result

.github/workflows/repro.yml:15:7: both "username" and "password" must be specified in "credentials" section [syntax-check]
.github/workflows/repro.yml:15:20: "credentials" section is scalar node but mapping node is expected [syntax-check]
.github/workflows/repro.yml:28:16: "container" section is alias node but mapping node is expected [syntax-check]
  • The first two errors misinterpret the fromJSON(...) expression as a scalar even though it produces the required mapping.
  • The third error is emitted because the lint job references the container anchor (*container-setup), which currently points to a mapping composed of expressions.

Expected Result

  • actionlint should accept a credentials value produced by expressions (especially when wrapped in fromJSON(...)) as long as the evaluated result is an object at runtime.
  • Re-using the same container definition via a YAML anchor should not be flagged when the anchor ultimately resolves to a mapping.

Additional Context

  • GitHub Actions runs this workflow without any issues; the expression correctly yields a {username, password} object only when both secrets are present, and {} otherwise.
  • We introduced temporary ignores in our repo (.github/linters/actionlint.yml) to keep CI green, but we would prefer to remove the ignore once actionlint handles this case.
  • Let me know if a smaller repro would help; happy to create one if needed.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions