build(lint): add surface linter (yamllint, shellcheck, actionlint)#81
build(lint): add surface linter (yamllint, shellcheck, actionlint)#81miru-agents wants to merge 7 commits into
Conversation
Add yamllint, shellcheck, and actionlint configuration plus a scripts/lint-surface.sh entrypoint that lints the repo's YAML files, shell scripts, and GitHub Actions workflows. - .yamllint.yml extends the default profile, disables document-start, downgrades line-length to warning, relaxes truthy/comments for GitHub Actions, and ignores the .agents subtree and generated api/specs. - .shellcheckrc disables SC1091 and intentionally sets no global shell= directive so mixed shebangs (sh/bash) are honored. - .github/actionlint.yml registers the ubuntu-latest-8c custom runner label used by release.yml. - scripts/lint-surface.sh excludes the .agents subtree, jinja template partials, and generated scripts/install output from shellcheck. https://claude.ai/code/session_019trxhNfR8bd4qN7bjjVKoe
Resolve the error-level findings the new surface linter reports: - builder.yml / .goreleaser.yaml: remove trailing blank lines. - .goreleaser.yaml / install.yaml: strip trailing spaces; add the missing final newline to install.yaml. - render.sh: drop the unused BLUE color variable (SC2034). - covgate.sh / update-covgates.sh: quote $SRC_DIR inside the parameter expansion (SC2295). https://claude.ai/code/session_019trxhNfR8bd4qN7bjjVKoe
Chain scripts/lint-surface.sh after the Rust lint in scripts/lint.sh so a local lint run (and therefore scripts/preflight.sh) exercises it, and add idempotent yamllint/shellcheck/actionlint installs to scripts/lib/install-lint-deps.sh. https://claude.ai/code/session_019trxhNfR8bd4qN7bjjVKoe
Add a surface-lint job that calls the shared reusable workflow mirurobotics/.github/.github/workflows/surface-lint.yml@main on ubuntu-latest, enforcing YAML / shell / GitHub Actions linting in CI. https://claude.ai/code/session_019trxhNfR8bd4qN7bjjVKoe
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 8286cb18e3
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| exec "$REPO_ROOT/scripts/lib/lint.sh" | ||
| "$REPO_ROOT/scripts/lib/lint.sh" | ||
|
|
||
| "$REPO_ROOT/scripts/lint-surface.sh" |
There was a problem hiding this comment.
Install surface linters before invoking lint-surface
In the CI lint job, the setup still only installs the Cargo linters (.github/workflows/ci.yml lines 30-35), but this new call now requires yamllint, shellcheck, and actionlint to already be on PATH because scripts/lint-surface.sh exits immediately when any of them is missing. On a clean runner or developer machine following the current lint setup, LINT_FIX=0 ./scripts/lint.sh fails before completing linting; install the surface tools in the lint job or run the updated dependency installer before this call.
Useful? React with 👍 / 👎.
…ss shellcheck Add shellcheck directives to the shebang-less jinja partials (shell=sh, plus narrow per-line/per-function disables for trap/logging-API false positives and cross-partial variable use), quote exit "$exit_code" in the cleanup trap, and keep the intentional $args word-splitting with a justified SC2086 disable. Regenerate scripts/install/*.sh from the templates and drop the jinja/install exclusions from lint-surface.sh so it lints the same surface as the shared CI workflow. https://claude.ai/code/session_019trxhNfR8bd4qN7bjjVKoe
The Rust lint CI job runs scripts/lint.sh, which now invokes scripts/lint-surface.sh. Surface linting is already enforced in CI by the dedicated surface-lint job (shared reusable workflow) that installs its own yamllint/shellcheck/actionlint toolchain, so requiring those tools in the Rust lint job is redundant and was failing the job. Guard the call with [ "$CI" != "true" ] so it still runs for local developer invocations, mirroring the existing CI guard in scripts/lib/install-lint-deps.sh.
shellcheck 0.11.x (used by the CI surface-lint action) reports the trap-invoked cleanup() function as SC2329 "function never invoked", whereas 0.9.x reports the equivalent SC2317 on its body. The directive only disabled SC2317, so CI still failed. Disable both codes so the suppression is robust across shellcheck versions, and regenerate the install scripts.
Summary
Ports the surface linter from the
coreandcli-privateGo repos to theagentRust repo. The surface linter lints non-code supporting files — YAML, shell scripts, and GitHub Actions workflows — usingyamllint,shellcheck, andactionlint, matching the existing pattern in the other Miru repos.All changes are scoped to YAML/shell/CI configuration. Zero changes to
src/— no Rust source is touched.What's included
scripts/lint-surface.sh(new) — runsyamllint,shellcheck, andactionlint, following agent script conventions (#!/bin/sh,set -e, 4-space indent). Excludes generated/templated artifacts (api/specs/, jinja partial templates,scripts/install/*)..yamllint.yml/.shellcheckrc(new) — config adapted to the agent repo's actual files. Generated OpenAPI specs underapi/specs/are added to the yamllintignore:block;.shellcheckrckeeps onlydisable=SC1091(no globalshell=sh, since the agent has mixed bash/sh shebangs)..github/actionlint.yml(new) — registers theubuntu-latest-8cself-hosted runner label (mirrorscli-private).scripts/lint.shnow chains surface lint after the Rust lint;scripts/lib/install-lint-deps.shinstalls the three tools idempotently.surface-lintjob in.github/workflows/ci.ymldelegating to the shared reusable workflowmirurobotics/.github/.github/workflows/surface-lint.yml@main(runs-on: ubuntu-latest).builder.yml,.goreleaser.yaml), trailing spaces + missing final newline (scripts/jinja/install.yaml), unusedBLUEvar (render.sh, SC2034), and unquoted$SRC_DIR(covgate.sh,update-covgates.sh, SC2295).Validation
./scripts/lint-surface.sh→ exit 0 (Surface lint complete). Onlyline-lengthwarnings remain (non-failing, same ascore/cli-private);shellcheckandactionlintreport nothing.LINT_FIX=0 ./scripts/lint.shruns the full Rust lint followed by the surface lint and completes successfully.Notes
preflightreports 2 failing tests insrc/deploy/filesys.rs(rollback_returns_errors_when_restores_fail_synthetic,remove_backups_continues_when_delete_fails). These are pre-existing and environmental — they assert that permission-denied filesystem operations fail, but the CI sandbox runs as root, which bypasses Unix permission enforcement. They are unrelated to this change, which touches no Rust source.Generated by Claude Code