Skip to content

build(lint): add surface linter (yamllint, shellcheck, actionlint)#81

Open
miru-agents wants to merge 7 commits into
mainfrom
claude/wizardly-hypatia-A3JyC
Open

build(lint): add surface linter (yamllint, shellcheck, actionlint)#81
miru-agents wants to merge 7 commits into
mainfrom
claude/wizardly-hypatia-A3JyC

Conversation

@miru-agents

Copy link
Copy Markdown
Collaborator

Summary

Ports the surface linter from the core and cli-private Go repos to the agent Rust repo. The surface linter lints non-code supporting files — YAML, shell scripts, and GitHub Actions workflows — using yamllint, shellcheck, and actionlint, 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) — runs yamllint, shellcheck, and actionlint, 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 under api/specs/ are added to the yamllint ignore: block; .shellcheckrc keeps only disable=SC1091 (no global shell=sh, since the agent has mixed bash/sh shebangs).
  • .github/actionlint.yml (new) — registers the ubuntu-latest-8c self-hosted runner label (mirrors cli-private).
  • Wiringscripts/lint.sh now chains surface lint after the Rust lint; scripts/lib/install-lint-deps.sh installs the three tools idempotently.
  • CI — new surface-lint job in .github/workflows/ci.yml delegating to the shared reusable workflow mirurobotics/.github/.github/workflows/surface-lint.yml@main (runs-on: ubuntu-latest).
  • Fixes for real findings — trailing blank lines (builder.yml, .goreleaser.yaml), trailing spaces + missing final newline (scripts/jinja/install.yaml), unused BLUE var (render.sh, SC2034), and unquoted $SRC_DIR (covgate.sh, update-covgates.sh, SC2295).

Validation

  • ./scripts/lint-surface.shexit 0 (Surface lint complete). Only line-length warnings remain (non-failing, same as core/cli-private); shellcheck and actionlint report nothing.
  • Negative test — appending trailing whitespace to a workflow file makes the linter exit 1 with the expected error; reverting restores exit 0.
  • LINT_FIX=0 ./scripts/lint.sh runs the full Rust lint followed by the surface lint and completes successfully.

Notes

preflight reports 2 failing tests in src/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

claude added 4 commits June 3, 2026 02:48
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

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 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".

Comment thread scripts/lint.sh Outdated
exec "$REPO_ROOT/scripts/lib/lint.sh"
"$REPO_ROOT/scripts/lib/lint.sh"

"$REPO_ROOT/scripts/lint-surface.sh"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge 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 👍 / 👎.

claude added 3 commits June 3, 2026 19:06
…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.
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.

2 participants