Skip to content

Update dependency jdx/jactionlint to v2 - #1429

Open
renovate[bot] wants to merge 1 commit into
mainfrom
renovate/jdx-jactionlint-2.x
Open

renovate[bot] wants to merge 1 commit into
mainfrom
renovate/jdx-jactionlint-2.x

Conversation

@renovate

@renovate renovate Bot commented Oct 12, 2026 •

Copy link
Copy Markdown
Contributor

Note

This PR body was truncated due to platform limits.

This PR contains the following updates:

Package Type Update Change
jdx/jactionlint major v1.8.2 → v2.5.0
jdx/jactionlint repository major v1.8.2 → v2.5.0

Note: The pre-commit manager in Renovate is not supported by the pre-commit maintainers or community. Please do not report any problems there, instead create a Discussion in the Renovate repository if you have any questions.


Release Notes

jdx/jactionlint

v2.5.0: : Run workflows locally with jactionlint run

Compare Source

jactionlint 2.5.0 adds jactionlint run, which runs the jobs of a workflow on your machine inside an OS sandbox, without a container engine. It also adds the unreachable-required-check rule, fixes two unpinned-images issues, and accepts the apm Dependabot ecosystem.

Added

jactionlint run: run workflows locally

jactionlint run lets you debug a run: script, an expression, a matrix or the needs wiring without pushing a commit. It shows what happened on your machine, not whether the workflow will pass on GitHub. Every skip or refusal is printed with its reason, and the run guide has a "Differences from GitHub" table. The workflow is first linted with the correctness profile, and the run stops on an error (--no-lint skips the lint). (#​316, #​317, #​319, #​320, #​321, #​322, #​323, #​324, @​jdx)

jactionlint run --list                    # jobs and matrix cells in dependency order, nothing runs
jactionlint run ci -j test                # run job `test` of .github/workflows/ci.yml and the jobs it needs
jactionlint run ci --dry-run              # the steps with ${{ }} replaced, nothing runs
jactionlint run ci -e pull_request --secret TOKEN=abc --var REGION=eu
jactionlint run --check-sandbox           # what this machine can enforce
  • Plan view. --list (--json for JSON) groups jobs into stages and expands matrices the way the runner does: exclude, then include. It evaluates name:, runs-on: and job if: expressions that it can, and marks each one if is true or if is false. The github context comes from git, -i NAME=VALUE sets workflow_dispatch inputs, and --event-file supplies github.event. A matrix built from needs outputs shows as "known at run time".
  • Steps and jobs. Supports run: steps with shell, working-directory, defaults.run, layered env, timeout-minutes and continue-on-error. Also supported: step and job outputs, needs.*.result, matrices with fail-fast, background and parallel: steps, the GITHUB_ENV/PATH/OUTPUT/STATE/STEP_SUMMARY file commands and workflow commands. Values from --secret and ::add-mask:: show as *** in all output. Jobs whose runs-on names a different OS are skipped. Ctrl-C cancels the steps, and steps with if: always() still run.
  • Actions and reusable workflows. Runs local, composite and JavaScript actions (with pre/post) and local or remote reusable workflows. If no Node.js on PATH has the right major version, jactionlint downloads it and checks it against the release's SHASUMS256.txt. Remote actions and reusable workflows must be pinned to a commit SHA. Use --trust-actions to resolve a tag or branch and print the commit it picked. actions/checkout, upload-artifact and download-artifact are replaced with local versions. Use --no-shim ACTION to run the real action.
  • Local actions cache. A cache service on 127.0.0.1 works with unmodified actions/cache, setup-*, jdx/mise-action and other actions built on @actions/cache, so a second run restores instead of downloading again. Caches are scoped to the ref and fall back to the default branch. Entries expire after 7 days, and the store has a 10 GB LRU limit (--cache-size). Related options: --cache=read-only|off, --no-cache, --cache-dir. Manage the store with jactionlint cache ls|rm|prune|path.
  • Network modes. --net=open is the default. --net=none blocks internet sockets. --net=proxy allows only a proxy that lets through GitHub and the common package registries. It needs Landlock ABI 4, which is Linux 6.7 or later. --allow-net HOST,... adds hosts, and --learn prints the hosts your steps contacted.
  • Containers (optional). container: jobs, services: and Docker actions run through docker or podman (--container-engine). By default all capabilities are dropped except nine, and no-new-privileges is set. jactionlint never runs privileged containers or mounts the host home or Docker socket. Images must be pinned by digest unless you pass --trust-images. options: is checked against an allow list: --privileged, --cap-add, -v, --network host and similar options are refused unless you pass --unsafe-container-options. Use --container to run Linux matrix cells in a digest-pinned ubuntu image, for example from a Mac. If no engine is installed, or you pass --no-containers, only the jobs and steps that need a container are skipped.
  • Parallel runs. --parallel N runs matrix cells and independent jobs at the same time. It respects needs and max-parallel, and prints each job's output in one block.
  • Explanations. Messages that end with (jactionlint run --explain ID) have a longer explanation. jactionlint run --explain list lists all of them.

Isolation and platform support: Each step runs with a filtered environment, a throwaway home, and a per-job copy of the workspace. Your checkout and real home cannot be read or written. Use --in-place to work in your checkout, --allow-read/--allow-write DIR to open more paths, and --sandbox=off to turn the sandbox off. If the sandbox can't be applied, the step does not run.

  • Linux: Landlock and seccomp-bpf, Linux 5.13 or later.
  • macOS: Seatbelt through sandbox-exec. This backend is new and has had much less use than the Linux one.
  • Windows: steps are refused. Use WSL2.
New rule: unreachable-required-check

The new unreachable-required-check rule reports a required check that no workflow will report for a change. GitHub waits forever for such a check, and the pull request cannot merge. Common causes are a missing merge_group trigger, a branches filter that leaves out the protected branch, and a paths filter that skips a README-only change. (#​331, @​mariusvniekerk)

The rule turns on in every profile when required-checks is in the config file:

required-checks:
  - name: CI gate
    events: [pull_request, merge_group]   # default: [pull_request]
    branches: [main]                      # optional, literal names

It reads every workflow in .github/workflows, so it doesn't report GitHub's workaround of a second workflow with the opposite paths filter. Each finding is placed where the fix goes: the config declaration (with a "did you mean" suggestion), on:, or the filter. When the answer depends on something the rule doesn't evaluate, it reports at level info and gives the reason. It does not read branch protection or rulesets from GitHub, so keep the list in sync with your repository settings. To turn the rule off, set rules: {unreachable-required-check: off}.

Fixed

  • unpinned-images now treats images built by drop-in forks of docker/build-push-action as local, the same as the original: useblacksmith/build-push-action, depot/build-push-action and warpbuilds/build-push-action. A later docker run of the image's tag is no longer reported. Other actions that take a tags: input are still reported. (#​328, @​jdx, @​tedserbinski)
  • unpinned-images now only treats an image as local when the same job builds, tags or loads it. Each job runs on its own runner, so docker run app:ci in a job that doesn't build app:ci pulls the image from the registry. That use is now reported. Previously, a build anywhere in the workflow hid the finding in every job. (#​329, @​jdx, @​tedserbinski)
  • dependabot-syntax accepts package-ecosystem: apm (Agent Package Manager), which GitHub added on November 3, 2026. (#​333, @​frottke)

New Contributors

Full Changelog: jdx/jactionlint@v2.4.0...v2.5.0

💚 Sponsor jactionlint

jactionlint is a fork of rhysd/actionlint, maintained by @​jdx, an open source developer at entire.io, the title sponsor of his open source work.

If jactionlint has a place in your development workflow, please consider becoming an individual or company sponsor. Your support funds ongoing development and helps keep jactionlint fast, free, and independent.

v2.4.0: : Private Use Area detection and fixes for artipacked, Dependabot groups and SARIF uploads

Compare Source

jactionlint 2.4.0 extends invisible-characters to report Private Use Area characters. It also fixes false positives in artipacked and dependabot-syntax, and stops the "inconsistent fingerprint" warnings when you upload SARIF to code scanning.

Added

  • invisible-characters reports Private Use Area characters (U+E000–U+F8FF and the two supplementary private-use planes). Most fonts have no glyph for these characters, so they can hide a payload that a script decodes at run time, the same way variation selectors can. The message calls them PRIVATE USE CHARACTER. The rule ID, profile, level and the fix that removes the character have not changed. If you use Nerd Font or Powerline icons on purpose, write them as escape sequences before you apply the fix. Otherwise the fix removes them. (#​311, @​jdx)

Fixed

  • artipacked no longer reports actions/checkout v6 and later. Starting with v6, checkout stores the credential in a file under $RUNNER_TEMP instead of the workspace, so uploading the workspace doesn't publish it. The rule skips v6+ tag refs, and also commit pins whose version comment says v6 or later. v5 and earlier are still reported. (#​308, @​jdx)
  • dependabot-syntax no longer reports an update with multi-ecosystem-group as a duplicate of the regular update for the same ecosystem and directory. Two updates are now duplicates only when they match on ecosystem, directory, target branch and group. Two ungrouped updates, or two updates in the same group, are still reported. (#​314, @​jdx)
  • SARIF output no longer writes primaryLocationLineHash. github/codeql-action/upload-sarif computes this value itself and logs an "inconsistent fingerprint" warning when a file supplies a different one. The fingerprint value is unchanged and is now stored under jactionlint/contextHash/v1 in partialFingerprints. If your tools read jactionlint's fingerprint from primaryLocationLineHash, switch them to the new key. (#​307, @​jdx)

Full Changelog: jdx/jactionlint@v2.3.0...v2.4.0

💚 Sponsor jactionlint

jactionlint is a fork of rhysd/actionlint, maintained by @​jdx, an open source developer at entire.io, the title sponsor of his open source work.

If jactionlint has a place in your development workflow, please consider becoming an individual or company sponsor. Your support funds ongoing development and helps keep jactionlint fast, free, and independent.

v2.3.0: : allow-unused for config ignores, and a Go toolchain fix for online checks

Compare Source

jactionlint 2.3.0 adds an allow-unused option to ignores entries in the config file and fixes a workflow-call-permissions false positive for OIDC. It is also built with Go 1.27.3, so online checks reject certificates from the compromised eMudhra CA.

Added

  • allow-unused for durable ignores. An ignores entry with allow-unused: true is not reported as unused-ignore when it suppresses nothing. Use it for findings that come and go, such as one caused by a moving tag. expired-ignore still reports the entry when it expires. The default is false, and any value other than true or false is a config error. The option is also in the config JSON Schema. (#​297, @​jdx)
    ignores:
      - rule: unpinned-uses
        uses: actions/cache
        reason: pinned by the Actions lock file on some branches
        allow-unused: true

Fixed

  • workflow-call-permissions no longer reports a missing id-token: write when the caller sets no permissions: and assume-default-permissions is permissive or not set. In that case, GitHub gives the called job an OIDC token. With assume-default-permissions: restricted, jactionlint still reports it. (#​299, @​jdx)
  • Online checks reject forged certificates from the compromised eMudhra CA. Release binaries are now built with Go 1.27.3, which rejects these certificate chains. Older binaries do not have this fix, so replace them with this release if you use --online. (#​301, @​jdalton)

New Contributors

Full Changelog: jdx/jactionlint@v2.2.0...v2.3.0

💚 Sponsor jactionlint

jactionlint is a fork of rhysd/actionlint, maintained by @​jdx, an open source developer at entire.io, the title sponsor of his open source work.

If jactionlint has a place in your development workflow, please consider becoming an individual or company sponsor. Your support funds ongoing development and helps keep jactionlint fast, free, and independent.

v2.2.0: : New rules, repository-aware CLI modes, and a PyPI package

Compare Source

jactionlint 2.2.0 adds about thirty new rules and extends many existing ones, mostly for script injection, token permissions, pinning and runner limits. It also adds CLI modes for pull request checks (--changed-since), rule discovery (--list-rules, --explain, shell completions), fact export and timeout suggestions, and publishes wheels to PyPI. Several new rules are in the default or correctness profile, so a run that was clean on 2.1.0 can show new findings. See Changed before you upgrade.

Highlights

  • More checks before a run fails: shell syntax errors without shellcheck, JavaScript syntax errors in actions/github-script, job permissions too narrow for the actions in the job, gh without a token, ubuntu-slim limits, github.event property typos, and validation of GitHub's Actions lock file.
  • Deeper security analysis: untrusted-checkout, cache-poisoning, template-injection and the secret rules follow more code paths. New pedantic and online rules cover command and argument injection, repojacking, release age, unpinned action dependencies and environments without required reviewers.
  • Better for CI and tooling: report only findings on changed lines, select single rules, export the repository model as JSON, get JSON Schemas for config and output, and install with pip/uvx.

Added

New rules in the default and correctness profiles
  • shell-syntax (default, error): reports syntax errors in bash/sh run: scripts, such as an unclosed quote or a missing fi/done, using a built-in parser. It runs only when shellcheck does not run, so the two never report the same error. (#​273, @​jdx)
  • insufficient-permissions (default, error): reports a job whose explicit permissions: miss a scope that one of its actions needs (upload-sarif, deploy-pages, OIDC logins, gh release create, git push and others, about 26 entries). missing-permissions --fix now uses the same table to write job-level permissions when the needs are exact. (#​192, @​jdx)
  • ubuntu-slim-limits (default, error): reports container:, services: and Docker container actions in jobs that run only on ubuntu-slim. With pedantic, it also reports timeout-minutes above 15. missing-timeout --fix limits its value to 15 for these jobs. (#​190, @​jdx)
  • actions-lock (default, error) and actions-lock-drift (online): check .github/workflows/actions.lock against the workflows. They report missing, stale and malformed entries. With --online, they also report replaced repositories, moved tags and commits that are on no branch or tag. Repositories without a lock file are not affected. unpinned-uses accepts a ref that the lock file pins to a commit. (#​237, #​228, @​jdx)
  • hardcoded-registry-credentials (default, error): reports plain-text passwords, tokens and keys in registries of dependabot.yml, including passwords embedded in a registry URL. (#​265, @​jdx)
  • gh-without-token (correctness): reports a gh command that needs a token in a step where no GH_TOKEN/GITHUB_TOKEN is set. (#​177, @​jdx)
  • environment-file-redirect (correctness): reports writes to GITHUB_OUTPUT (and similar files) without the $, and a > that overwrites data the same script already wrote. It has a fix: safe for the missing $, unsafe for >. (#​184, @​jdx)
  • github-script-syntax (correctness): checks the script input of actions/github-script with node --check. It knows the argument names of each action version, so it catches errors like const glob = require(...). It needs Node.js 20 or later on PATH; without it, the rule is skipped and a note says so. (#​242, @​jdx)
  • malformed-expression-delimiters (correctness): reports ${ github.ref }, $ {{ x }} and {{ github.sha }}. (#​180, @​jdx)
  • multiline-plain-run (correctness): reports a multi-line run: that YAML folds into a single line. (#​205, #​256, @​jdx)
  • concurrency-deadlock (correctness): reports a concurrency group that a workflow shares with a local reusable workflow it calls. GitHub cancels such runs as a deadlock. (#​210, @​jdx)
  • conflicting-action-inputs (correctness), plus new missing-action-input cases: report input combinations of well-known actions that cannot work, for example download-artifact name with artifact-ids, or nick-fields/retry without exactly one timeout input. (#​207, @​jdx)
  • undefined-property now checks github.event.* property names against the webhook payloads, down to three levels. By default, it reports only names that no event has. The strict-event-payloads option, on in the pedantic profile, also reports properties that the workflow's own triggers don't have. (#​249, @​jdx)
New pedantic rules
  • deprecated-runner-label: warns about runner labels with an announced retirement date (macos-14, ubuntu-22.04), with replacement labels. (#​182)
  • deprecated-node-runtime: reports runs.using: node20/16/12 in action metadata, popular actions at majors that declare node20, and environment variables that select the Node.js runtime. (#​225, #​230, #​234)
  • command-injection: reports untrusted input that was moved to env: but then runs as code (eval, bash -c, python -c, execSync in github-script, and similar). (#​202)
  • argument-injection: reports free text in the program of sed/awk, in find -exec, or as a leading word of tar, curl, git clone and others. (#​221)
  • output-clobbering: reports input that can contain line breaks written to GITHUB_OUTPUT as a single record. (#​212)
  • comment-trigger-authorization: reports comment-triggered jobs that don't check who commented. (#​217)
  • event-name-never-received: reports github.event_name compared with an event the workflow never receives. (#​214)
  • fail-fast-action-inputs: reports actions configured to pass when they produced nothing. (#​196)
  • macos-gnu-flags: reports GNU-only options in run scripts of macOS jobs. (#​241)
  • unmatched-paths-filter: reports paths filters that match no file in the repository. (#​238)
  • missing-version-comment: reports a commit-SHA pin without a version comment. --online --fix adds the comment. (#​232)
  • unused-workflow-secret: reports on.workflow_call.secrets that nothing reads. (#​223)

All by @​jdx.

New online rules
  • repojacking: reports an action or reusable workflow whose owner name anyone could register. It runs on github.com only. (#​248, @​jdx)
  • unpinnable-action: reports an action pinned by hash whose own dependencies are not pinned. (#​240, @​jdx)
  • action-release-cooldown (opt-in): reports an action at a version released less than N days ago. It is off until the config has an entry for it:
    rules:
      action-release-cooldown: { level: warning, days: 7 }
    (#​235, @​jdx)
Extensions to existing rules
  • untrusted-checkout follows the pull request revision through variables, script files, pull/N/head fetches, local reusable workflows and composite actions. It now covers issue_comment workflows that build a pull request, and reports gates that pass once in front of code that can change. It honors the fork protection of actions/checkout, and counts actions that run the workspace and the input that makes them do it. (#​159, #​175, #​203, #​206, #​208, #​213, #​220, @​jdx)

  • With --online, environments are checked: untrusted-checkout, untrusted-artifact and agentic-actions no longer trust an environment: that has no required reviewers, or that doesn't exist in a public repository. (#​247, @​jdx)

  • cache-poisoning:

    • A build job that uploads artifacts for a publishing job counts as a release job, even with a read-only token.
    • More publishers are recognized, including docker/build-push-action with an expression for push, plus maturin and sccache caches, pnpm/setup, graalvm and composer.
    • Caches of credential files are reported.
    • A new pedantic option adds zizmor's heuristics for tag-triggered and release-branch workflows.

    (#​160, #​216, @​jdx)

  • template-injection reports more outsider-controlled free text in the default profile: previous titles and bodies of edited issues, the fork homepage, wiki page titles, merge queue commit messages, and workflow_run paths. (#​173, @​jdx)

  • dangerous-triggers messages say which token scopes the workflow can write and which secrets it reads. (#​189, @​jdx)

  • github-env follows text that a script reads with gh and git. (#​218, @​jdx)

  • unpinned-images checks docker run images in scripts and adds per-image policies and image allow/deny lists. --online --fix=unsafe pins container images to a digest. (#​211, #​239, @​jdx)

  • unpinned-uses accepts the tag of an immutable release under --online. --online --fix names the most specific version tag in the comment it writes. (#​251, #​224, @​jdx)

  • ref-version-mismatch reads ratchet comments and can fix the version comment (unsafe). (#​227, @​jdx)

  • workflow-secret-scope has a job-level option. secrets-outside-env now reports secrets passed to reusable workflows. (#​223, @​jdx)

  • More pedantic options:

    • unlocked-install reports npm/yarn/bun/aube installs that run lifecycle scripts or have no release-age cooldown.
    • untrusted-artifact knows more download actions and reports downloads of every artifact.
    • use-trusted-publishing reports jobs that build, have no environment, or drop attestations.
    • unredacted-secrets reports values cut from a secret and printed by a script.
    • concurrency-limits reports schedule-only and manual-only workflows.

    (#​187, #​201, #​255, #​219, #​209, #​222, #​266, @​jdx)

  • aube is recognized wherever npm, pnpm, yarn and bun are. (#​254, @​jdx)

  • Runner labels:

    • Labels of Blacksmith, Depot, Namespace, RunsOn, Ubicloud and WarpBuild are accepted. Limit them with self-hosted-runner.providers.
    • Labels built from a matrix value and text are checked.
    • self-hosted-runner counts the configured labels and runner groups, and says when a pull request reaches the runner.

    (#​199, #​233, #​194, @​jdx)

  • github-app checks two more token actions, and dependabot-missing-actions-update covers local composite actions. (#​229, @​jdx)

  • superfluous-actions resolves runs-on expressions that the repository defines. (#​271, @​jdx)

  • missing-timeout has an accept-step-timeouts option for jobs whose steps all set timeout-minutes. (#​252, @​jdx)

Online checks
  • With --online, the inputs of any remote action outside the built-in data set are checked against its action.yml at the pinned ref. Calls of reusable workflows in other repositories are checked the same way. (#​231, #​236, @​jdx)
  • On GitHub Enterprise Server, actions from github.com can be looked up on github.com. (#​250, @​jdx)
  • --online-report=FILE writes online coverage and cache freshness as JSON, for any output format. The SARIF output gets the same fields. (#​166, @​jdx)
CLI and configuration
  • --changed-since REV shows only findings on lines changed since the merge base with REV, for pull request checks. --changed-scope files shows every finding in a changed file. The whole repository and call graph are still analyzed. A missing merge base, for example in a shallow clone, exits with status 3. (#​274, #​279, @​jdx)
    jactionlint --changed-since origin/main
  • --select=RULES reports only the named rules. --no-ignores disables inline ignores, config ignores and the baseline. --list-rules lists all rules, also as JSON. (#​200, @​jdx)
  • --explain RULE prints a rule's documentation, options, fix prerequisites and examples, offline. --completion=bash|zsh|fish|powershell prints a shell completion script. (#​204, #​269, @​jdx)
  • --show-fix-status shows under each finding whether a fix is available and how to apply it, and more fixable rules say why a finding has no fix. SARIF output explains a missing fix as well. (#​269, #​164, @​jdx)
  • --show-doc-urls and --finding-context (events and token permissions on each JSON/SARIF finding) add details to the output. --ruff=CMD checks Python scripts with ruff instead of pyflakes. The config key platform: forgejo|gitea accepts full-URL uses: references to other hosts. Jujutsu (.jj) workspaces are detected as project roots. (#​215, @​jdx)
  • --export-facts prints the events, permissions, concurrency, jobs, steps and calls of a repository as versioned JSON, for jq or policy tools. --print-facts-schema prints its schema. (#​272, @​jdx)
  • --suggest-timeouts reports how long each job took in its latest successful runs and suggests a timeout-minutes value. It is a report only and changes no files. (#​275, @​jdx)
  • JSON Schemas for the config file and for --format json output are available through --print-config-schema and --print-output-schema. --init-config adds a yaml-language-server schema comment. (#​195, @​jdx)
  • A new shellcheck: config section sets rcfile, args and enable. The --shellcheck-rcfile=FILE flag overrides rcfile. (#​191, @​jdx)
  • A note says when shellcheck, pyflakes or node did not run. (#​188, @​jdx)
Installation
  • Wheels are published to PyPI, so jactionlint can be installed with pip, pipx, uv tool or uvx. (#​277, @​jdx)
    uvx jactionlint
  • The pre-commit hooks now also run when action.yml or dependabot.yml changes. A new jactionlint-shellcheck hook builds shellcheck into the hook environment. (#​181, @​jdx)

Changed

  • New findings on existing workflows. The new default and correctness rules above, the new template-injection contexts and the wider cache-poisoning coverage can report on workflows that passed on 2.1.0. actions-lock reports only in repositories with an Actions lock file. Popular actions pinned to a full version, or to a commit with a version comment, now get their inputs checked. (#​174, @​jdx)

  • Stricter syntax checks. These are now reported because GitHub rejects them: a schedule entry without cron, merge_group types other than checks_requested, $/path@ref, $/ paths that leave the repository or don't exist, timeout-minutes in composite steps, unsupported contexts in action input defaults, and expressions in uses:. (#​186, @​jdx)

  • Runner label retirements: unknown-runner-label will start reporting macos-14 on 2026-11-02 and ubuntu-22.04 on 2027-04-17. Each finding names the retirement date and replacement labels. Before those dates, only the pedantic deprecated-runner-label warns. (#​182, @​jdx)

  • Fewer default findings:

    • dangerous-triggers reports a workflow that has no write scopes and reads no secrets only with pedantic. (#​189)
    • cache-poisoning reports docker/setup-buildx-action only when version is set. pedantic restores the old behavior. (#​160)
    • Hosted-runner provider labels are no longer unknown. (#​199)

    All by @​jdx.

  • A broken extends is now an error. In a discovered config file, an extends entry that points to a missing file exits with status 3. Before, the whole config was silently skipped. (#​285, @​jdx)

  • Ignore comments inside scripts no longer apply. An own-line # jactionlint ignore= inside a run: | block or another multi-line string has no effect. Only real YAML comments are read. (#​284, @​jdx)

  • Go API:

    • NewLinter(out, nil) no longer panics.
    • Error.PrettyPrint prints the rule ID instead of the kind. Error() is unchanged.
    • ExprSemanticsChecker rejects every context unless SetContextAvailability is called.

    (#​283, @​jdx)

Fixed

  • False positives:
    • Keys and values that the workflow schema allows but the docs don't list are accepted. (#​170)
    • A whole mapping or list written as one expression is accepted where the schema allows it. (#​178)
    • if-always-true no longer reports the trailing newlines of a block scalar. (#​226)
  • Missing findings:
    • -latest runner labels are matched to the images behind them. (#​171)
    • Permission findings of the pedantic profile are reported again. (#​176)
    • untrusted-checkout skips merged pull requests and counts sed -f, awk -f, tar -P and unzip -:. (#​175)
  • --changed-since counts findings that several files share once, keeps ..foo paths inside the repository, and refuses --export-facts. (#​279)
  • download-jactionlint.bash: a missing release now prints a clear error instead of a gzip error. The script accepts amd64 (FreeBSD), and its help text is corrected. (#​282)
  • --help and messages: --help and several online and --migrate-ignores messages now match the documented behavior. (#​287)

All by @​jdx.

Performance

  • Peak memory is lower on very large repositories because fewer workflows are checked at the same time. (#​158)
  • Each run script is analyzed once, the callers of an action are parsed once, and parsed expressions are shared between rules. (#​270, #​165)
  • The --online checks read the advisories of all actions with one request. (#​268)

All by @​jdx.

Full Changelog: jdx/jactionlint@v2.1.0...v2.2.0

💚 Sponsor jactionlint

jactionlint is a fork of rhysd/actionlint, maintained by @​jdx, an open source developer at entire.io, the title sponsor of his open source work.

If jactionlint has a place in your development workflow, please consider becoming an individual or company sponsor. Your support funds ongoing development and helps keep jactionlint fast, free, and independent.

v2.1.0: : JACTIONLINT_ONLINE, workflow-secret-scope, and more precise security rules

Compare Source

jactionlint 2.1.0 adds an environment variable that turns on the online checks, a new workflow-secret-scope rule, and machine-readable reasons when a finding has no fix. Many security rules now produce fewer false positives, especially in reusable workflows and release pipelines. Some rules now report things they did not report before, so an existing clean run can show new findings (see Changed).

Added
  • JACTIONLINT_ONLINE environment variable. It turns on the online checks without changing the command, so CI can run them while local pre-commit hooks stay offline. 1, true or on works like --online, and cache, strict or cache,strict select a mode. 0, false, off or no works like --no-online and overrides online: true in the config file. The --online/--no-online flags override the variable, and the variable overrides the config file. An invalid value exits with status 2. (#​155, @​jdx)
    - run: hk check --all
      env:
        JACTIONLINT_ONLINE: 1
        GITHUB_TOKEN: ${{ github.token }}
  • New workflow-secret-scope rule (security, pedantic profile, warning, no autofix). It reports a named secret in workflow-level env: when steps in two or more jobs can see it. The rule skips single-job workflows, GITHUB_TOKEN, jobs or steps that override the variable, and jobs that call reusable workflows. (#​136, @​jdx)
  • background-step-not-waited (correctness profile, from parallel-steps). It reports reads of a background step's outputs, outcome or conclusion before a wait or wait-all covers that step. Those reads evaluate to an empty string. Steps with background: ${{ ... }} are not tracked. (#​132, @​jdx)
  • Reasons for missing fixes. When a fixable rule has no fix for a finding, the finding now says why. This applies to missing-timeout, dependabot-cooldown, unpinned-uses, template-injection and artipacked. The reason appears as no_fix in JSON and template output, and as noFixCode, noFixReason and noFixOption properties in SARIF. The codes are option-required, option-invalid, online-required, lookup-failed, unsupported-shape and needs-judgment. Text output is unchanged. When default-minutes or default-days is not set, the missing-timeout and dependabot-cooldown messages now say which option to set to enable --fix. (#​135, #​147, #​154, @​jdx)
  • Online check coverage in SARIF. When online checks are on, SARIF runs include properties.onlineCoverage with status (complete/incomplete), mode, skippedLookups, excludedRepositories and evidence (network or cache). (#​140, @​jdx)
Changed
  • excessive-permissions now reports workflow-level write scopes in single-job workflows too, unless the trigger is privileged. Any job added later would inherit those scopes without notice. (#​152, @​jdx)
  • missing-permissions no longer reports workflows whose only trigger is workflow_call, because the callers decide the token permissions. Workflows that have workflow_call plus another trigger are still reported. They now get an unsafe fix (contents: read, applied only with --fix=unsafe), and the message says the permissions must not exceed what callers grant. (#​138, #​152, @​jdx)
  • Parallel-step control keys now match what GitHub accepts. On wait, wait-all and cancel steps, only id and name are allowed besides the keyword. On parallel steps, only parallel is allowed. wait-all: false is now an error. To apply a condition, put if: on a step inside the parallel group instead of on the group. (#​128, [@&#

[!IMPORTANT]
✂ PR body was truncated to here.


Configuration

📅 Schedule: (UTC)

  • Branch creation
    • At any time (no schedule defined)
  • Automerge
    • At any time (no schedule defined)

🚦 Automerge: Enabled.

♻ Rebasing: Whenever PR is behind base branch, or you tick the rebase/retry checkbox.

🔕 Ignore: Close this PR and you won't be reminded about these updates again.


  • If you want to rebase/retry this PR, check this box

This PR was generated by Mend Renovate. View the repository job log.

@renovate
renovate Bot enabled auto-merge (squash) October 12, 2026 14:42
@renovate
renovate Bot requested a review from andrewaylett October 12, 2026 14:42
@renovate
renovate Bot force-pushed the renovate/jdx-jactionlint-2.x branch 10 times, most recently from 80fa9c7 to 050a715 Compare October 14, 2026 19:49
@renovate
renovate Bot force-pushed the renovate/jdx-jactionlint-2.x branch 13 times, most recently from 73441d6 to bd1172f Compare October 23, 2026 11:07
@renovate
renovate Bot force-pushed the renovate/jdx-jactionlint-2.x branch 22 times, most recently from 264a072 to 26b3007 Compare November 2, 2026 16:12
@renovate
renovate Bot force-pushed the renovate/jdx-jactionlint-2.x branch 7 times, most recently from c59335c to 65caf35 Compare November 4, 2026 01:15
Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant