Skip to content

Tie handoff claims to the commands that produced them #194

Tie handoff claims to the commands that produced them

Tie handoff claims to the commands that produced them #194

Workflow file for this run

name: Dotfiles CI
on: # yamllint disable-line rule:truthy
pull_request:
push:
branches: [main]
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
permissions:
contents: read
statuses: write
jobs:
lint:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v7
with:
# super-linter resolves the default branch at startup and exits fatally if neither main
# nor origin/main is present. That check is unconditional, so the history is needed even
# though VALIDATE_ALL_CODEBASE means nothing is ever diffed against it.
fetch-depth: 0
- name: Check zsh syntax
# Nothing else here checks this shell code. ShellCheck has no zsh dialect, and
# super-linter never hands it these files anyway: a .zsh extension is routed to the
# bash-exec and shfmt arrays but never to the one ShellCheck reads, .zshrc classifies as a
# "zsh script" and reaches the same dead end, and the extensionless autoload functions
# under home/.zsh/functions look like plain text and join no linter's list at all. So
# `zsh -n` is the only syntax gate these files have. It parses without executing, which
# also means it catches parse errors only, not undefined variables or missing commands.
# ubuntu-latest does not ship zsh, hence the install.
run: |
sudo apt-get update
sudo apt-get install --yes zsh
# Discovered rather than listed: everything under home/.zsh is zsh by construction,
# so a file added there is covered without anyone remembering to come back here. The
# anti-glob reasoning on the autoload line in home/.zshrc does not apply — there a glob
# is dangerous because every fpath entry becomes a live command name, so over-coverage
# is the hazard. For a syntax check it is under-coverage that hurts, and parsing a file
# that did not need it costs nothing.
files=(home/.zshrc)
while IFS= read -r file; do files+=("${file}"); done < <(find home/.zsh -type f | sort)
# An empty result would run the loop zero times and pass green while checking nothing —
# the exact shape of the gap this step exists to close. Fail loudly instead.
if [ "${#files[@]}" -lt 2 ]; then
echo "Found no zsh files under home/.zsh; has the directory moved?" >&2
exit 1
fi
failed=0
for file in "${files[@]}"; do
echo "::group::zsh -n ${file}"
zsh -n "${file}" || failed=1
echo "::endgroup::"
done
exit "${failed}"
- name: Check the README's plugin table matches .zshrc
run: |
zshrc=$(sed -n 's/^plugins=(\(.*\))$/\1/p' home/.zshrc | tr ' ' '\n' | sort)
readme=$(grep -oP '^\s*\| \[\K[a-z-]+(?=\]\[omz_)' README.md | sort)
if [ -z "${zshrc}" ]; then
echo "Found no plugins=() array in home/.zshrc; has the line changed shape?" >&2
exit 1
fi
if [ -z "${readme}" ]; then
echo "Found no [name][omz_*] rows in README.md; has the table changed shape?" >&2
exit 1
fi
if ! diff <(echo "${zshrc}") <(echo "${readme}"); then
echo "::error::plugins=() in home/.zshrc and the README's plugin table disagree." >&2
echo "Above, < is in .zshrc only and > is in the README only." >&2
exit 1
fi
- name: Run the linters
uses: super-linter/super-linter/slim@v8.7.0
env:
# To report GitHub Actions status checks
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
ENABLE_GITHUB_PULL_REQUEST_SUMMARY_COMMENT: false
VALIDATE_ALL_CODEBASE: true # lint every file, not only the ones that changed
VALIDATE_BASH: true
VALIDATE_GITHUB_ACTIONS: true
VALIDATE_GITLEAKS: true
VALIDATE_GIT_MERGE_CONFLICT_MARKERS: true
VALIDATE_JSON: true
VALIDATE_MARKDOWN: true
VALIDATE_YAML: true
LINTER_RULES_PATH: /