Skip to content

Add a CLI action for runners without a Docker daemon - #92

Draft
kjanat wants to merge 3 commits into
masterfrom
cli-action-mise
Draft

kjanat wants to merge 3 commits into
masterfrom
cli-action-mise

Conversation

@kjanat

@kjanat kjanat commented Sep 1, 2026

Copy link
Copy Markdown
Owner

The Docker action needs a reachable daemon, so ubuntu-slim cannot use it. The workaround the docs carried until now reconstructed the release asset name in shell, and it was wrong on two of the three runner platforms.

Measured, the old snippet against the real assets
$ gh release view --repo kjanat/actionlint --json tagName,assets --jq '.tagName, (.assets[].name)'
v1.13.0
actionlint_1.13.0_checksums.txt
actionlint_1.13.0_darwin_amd64.tar.gz
actionlint_1.13.0_darwin_arm64.tar.gz
actionlint_1.13.0_freebsd_386.tar.gz
actionlint_1.13.0_freebsd_amd64.tar.gz
actionlint_1.13.0_linux_386.tar.gz
actionlint_1.13.0_linux_amd64.tar.gz
actionlint_1.13.0_linux_arm64.tar.gz
actionlint_1.13.0_linux_armv6.tar.gz
actionlint_1.13.0_windows_386.zip
actionlint_1.13.0_windows_amd64.zip
actionlint_1.13.0_windows_arm64.zip

The snippet built its pattern as actionlint_*_${RUNNER_OS,,}_${asset_arch}.tar.gz. On a macOS runner RUNNER_OS is macOS, so that lowercases to macos while the assets say darwin. On Windows the assets are .zip, so the pattern matches nothing and tar -xzf could not have unpacked it anyway. It also ran actionlint -color with no problem matcher registered, so problems stayed in the step log and never became annotations.

This adds action/cli, a composite action that installs actionlint with mise and registers the problem matcher.

mise picks the release asset itself, which removes the hand-written OS and architecture mapping entirely. No asset_pattern is needed for our naming.

Measured, mise against our releases
$ MISE_MINIMUM_RELEASE_AGE=0s mise x "github:kjanat/actionlint@latest" -- actionlint --version
1.13.0
installed by downloading from release page
built with go1.27.0 compiler for linux/amd64

minimum_release_age defaults to 24 hours, so the action sets it to 0s in its inline mise_toml. Without that a fresh actionlint release is not installable for a day.

shellcheck resolves through the registry; pyflakes is not in it and goes through pipx:pyflakes.

$ mise registry | grep -E "^(shellcheck|pyflakes) "
shellcheck                    aqua:koalaman/shellcheck asdf:luizm/asdf-shellcheck

The action ships its own copy of the generated matcher. Until now docs/usage.md told readers to copy actionlint-matcher.json into their own repository before annotations worked, which the action can simply do for them.

That copy is generated, not hand-maintained. make matcher writes both files from scripts/generate-actionlint-matcher/main.mjs, and the existing up-to-date guard in .github/workflows/matcher.yaml compares the whole tree, so it covers both without further changes.

actionlint/Makefile

Lines 113 to 116 in 7dc7818

.github/actionlint-matcher.json action/cli/actionlint-matcher.json: scripts/generate-actionlint-matcher/object.mjs
node ./scripts/generate-actionlint-matcher/main.mjs $@
matcher: .github/actionlint-matcher.json action/cli/actionlint-matcher.json

A new CI job runs the action on ubuntu-slim, the runner the Docker action cannot reach. That reference also puts the action under actionlint's own composite-step validation, which I confirmed by breaking it on purpose.

Measured, the action is actually validated
$ sed -i 's|^    - shell: bash$|    - shell: bash\n      bogus-key: true|' action/cli/action.yml
$ ./actionlint -color
action/cli/action.yml:48:7: step 2 in "runs.steps" section in metadata of "actionlint CLI by @kjanat" action has unexpected key "bogus-key". expected one of "continue-on-error", "env", "id", "if", "name", "run", "shell", "working-directory" [action]
   |
48 |     - shell: bash
   |       ^~~~~~

Reverted afterwards. With the file restored, ./actionlint -color -shellcheck 'shellcheck -o all', check-readme, check-checks and dprint check all pass.

The flags input is split on whitespace with read -ra rather than an unquoted expansion, so it needs no shellcheck disable comment and does not glob.

Not in this PR

action/compat, a variant that downloads a second release binary to reach full input and output parity with the Docker action, plus the .goreleaser.yaml change that would publish that binary. Both sit uncommitted pending a separate decision on whether one action or two is the right answer.

The Docker action needs a daemon, so ubuntu-slim cannot use it. The
workaround the docs carried reconstructed the release asset name by hand
and got it wrong on macOS, where the assets say darwin rather than macos,
and on Windows, where they are zip rather than tar.gz. It also ran the
binary without a problem matcher, so nothing appeared as an annotation.

The new action installs actionlint with mise, which selects the asset for
the runner itself, and ships the generated matcher so callers no longer
copy actionlint-matcher.json into their own repository.

"make matcher" now writes both copies of that generated file, and the
existing up-to-date guard covers them.
@coderabbitai

coderabbitai Bot commented Sep 1, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are limited based on label configuration.

🏷️ Required labels (at least one) (1)
  • cr:review
🚫 Excluded labels (none allowed) (2)
  • wip
  • cr:skip

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Essentials

Run ID: 800b6686-e223-4fa1-b7f4-3e31da0a76bb

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Comment @coderabbitai help to get the list of available commands.

Rewriting the daemon-less section split the sentence across two lines, so
the bump-version rule that matches it found no occurrence and
TestDeclaredTargetsMatchRepository failed.
The action installs the published actionlint, which is older than this
branch, so pointing it at the repository reported the self-repository
"uses:" syntax, "concurrency.queue" and the parallel step keywords as
errors. Those are features the release does not carry yet.

A fixture workflow written to the runner's temp directory keeps the job
about what it is meant to prove: that the action installs actionlint on a
runner without a Docker daemon and runs it.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant