Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 65 additions & 0 deletions .github/actions/shellcheck/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
name: shellcheck
description: Lint shell scripts with ShellCheck against a caller-supplied rcfile.

inputs:
paths:
description: >-
Roots to search for shell scripts (*.sh, *.bash), space-separated.
Default searches the whole repo.
default: '.'
rcfile:
description: Path to the .shellcheckrc ruleset in the caller repo.
default: modules/shellcheck/.shellcheckrc
exclude:
description: >-
Path substrings to skip, space-separated (e.g. intentionally-bad
fixtures). The .git directory is always skipped.
default: ''
version:
description: Exact ShellCheck version to install.
default: 0.11.0
sha256:
description: >-
SHA-256 of the linux x86_64 .tar.gz release asset for `version`. Change
together with `version`.
default: b7af85e41cc99489dcc21d66c6d5f3685138f06d34651e6d34b42ec6d54fe6f6

runs:
using: composite
steps:
- name: Install ShellCheck
shell: bash
env:
VERSION: ${{ inputs.version }}
SHA256: ${{ inputs.sha256 }}
run: |
set -euo pipefail
url="https://github.com/koalaman/shellcheck/releases/download/v${VERSION}/shellcheck-v${VERSION}.linux.x86_64.tar.gz"
curl -fsSL "$url" -o shellcheck.tar.gz
echo "${SHA256} shellcheck.tar.gz" | sha256sum -c -
tar -xzf shellcheck.tar.gz "shellcheck-v${VERSION}/shellcheck"
sudo install "shellcheck-v${VERSION}/shellcheck" /usr/local/bin/shellcheck
rm -rf shellcheck.tar.gz "shellcheck-v${VERSION}"
shellcheck --version

- name: Run ShellCheck
shell: bash
env:
PATHS: ${{ inputs.paths }}
RCFILE: ${{ inputs.rcfile }}
EXCLUDE: ${{ inputs.exclude }}
run: |
set -euo pipefail
# $PATHS unquoted so multiple roots word-split.
mapfile -t files < <(find $PATHS -type f \( -name '*.sh' -o -name '*.bash' \) -not -path '*/.git/*' | sort)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Fail on missing search roots

When a caller mistypes or renames an input root, find reports the missing path but exits inside this process substitution, so mapfile still returns success under set -e; the action then either lints only the remaining roots or prints No shell scripts to check. and exits 0. This can let a misconfigured ShellCheck lane pass without checking the intended scripts, so validate each paths entry or otherwise propagate find failures before continuing.

Useful? React with 👍 / 👎.

# Drop excluded substrings (space-separated, fixed-string match).
for sub in $EXCLUDE; do
mapfile -t files < <(printf '%s\n' "${files[@]}" | grep -vF -- "$sub" || true)
done
if [[ ${#files[@]} -eq 0 ]]; then
echo 'No shell scripts to check.'
exit 0
fi
printf 'Checking %d file(s):\n' "${#files[@]}"
printf ' %s\n' "${files[@]}"
shellcheck --rcfile="$RCFILE" "${files[@]}"
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ via `$GITHUB_ACTION_PATH` without any checkout of this repo.
- `.github/actions/markdown` — markdownlint-cli2 over the repo's markdown.
- `.github/actions/powershell` — PSScriptAnalyzer over the repo's PowerShell,
via the bundled `Invoke-Pssa.ps1` (per-file subprocess isolation).
- `.github/actions/shellcheck` — ShellCheck over the repo's shell scripts
(installs a pinned, checksum-verified binary).

Each input's meaning and default is documented inline in the action's `inputs:`
block.
Expand Down