diff --git a/CI/linters/clippy.yml b/CI/linters/clippy.yml new file mode 100644 index 0000000..9bdd9eb --- /dev/null +++ b/CI/linters/clippy.yml @@ -0,0 +1,33 @@ +clippy: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Set up Rust toolchain + uses: dtolnay/rust-toolchain@stable + with: + components: clippy + + - name: Cache Cargo registry and target + uses: actions/cache@v4 + with: + path: | + ~/.cargo/registry + target/ + key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} + restore-keys: | + ${{ runner.os }}-cargo- + + - name: Run Clippy + run: | + set -euo pipefail + + if [[ ! -f "Cargo.toml" ]]; then + echo "::error::No Cargo.toml found" + exit 1 + fi + + echo "ℹ️ Running Clippy..." + cargo clippy --all-targets --all-features -- -D warnings \ + && echo "✅ Clippy passed" \ + || { echo "❌ Clippy found issues"; exit 1; } diff --git a/README.md b/README.md index e384bed..2d2ca2d 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,7 @@ that projects compose into their own workflows. | gitleaks | security | [CI/security/gitleaks.yml](https://github.com/prog-time/workflows/blob/main/CI/security/gitleaks.yml) | | trivy | security | [CI/security/trivy.yml](https://github.com/prog-time/workflows/blob/main/CI/security/trivy.yml) | | semgrep | security | [CI/security/semgrep.yml](https://github.com/prog-time/workflows/blob/main/CI/security/semgrep.yml) | +| Clippy | linters | [CI/linters/clippy.yml](https://github.com/prog-time/workflows/blob/main/CI/linters/clippy.yml) | | ESLint | linters | [CI/linters/eslint.yml](https://github.com/prog-time/workflows/blob/main/CI/linters/eslint.yml) | | golangci-lint | linters | [CI/linters/golangci-lint.yml](https://github.com/prog-time/workflows/blob/main/CI/linters/golangci-lint.yml) | | Hadolint | linters | [CI/linters/hadolint.yml](https://github.com/prog-time/workflows/blob/main/CI/linters/hadolint.yml) | @@ -68,6 +69,7 @@ Workflows/ │ ├── assemble-ci.sh # assembles source YAMLs → CI/ │ ├── CI/ # source YAML templates │ │ ├── linters/ +│ │ │ ├── clippy.yml │ │ │ ├── eslint.yml │ │ │ ├── golangci-lint.yml │ │ │ ├── hadolint.yml @@ -97,6 +99,7 @@ Workflows/ │ │ └── rspec.yml │ └── shell/ # bash scripts (one per tool) │ ├── linters/ +│ │ ├── clippy.sh │ │ ├── eslint.sh │ │ ├── golangci-lint.sh │ │ ├── hadolint.sh @@ -124,6 +127,7 @@ Workflows/ ├── tests/ │ ├── assemble-ci.bats # tests for the assembler │ ├── linters/ # unit tests for each shell script +│ │ ├── clippy.bats │ │ ├── hadolint.bats │ │ ├── htmlhint.bats │ │ ├── markdownlint.bats @@ -214,6 +218,7 @@ shellcheck: | Snippet | Tool | What it checks | |---------|------|----------------| +| `CI/linters/clippy.yml` | [clippy](https://github.com/rust-lang/rust-clippy) | Rust | | `CI/linters/eslint.yml` | [eslint](https://eslint.org) | JavaScript / TypeScript | | `CI/linters/golangci-lint.yml` | [golangci-lint](https://golangci-lint.run) | Go | | `CI/linters/hadolint.yml` | [hadolint](https://github.com/hadolint/hadolint) | Dockerfiles | diff --git a/scripts/CI/linters/clippy.yml b/scripts/CI/linters/clippy.yml new file mode 100644 index 0000000..a5ff569 --- /dev/null +++ b/scripts/CI/linters/clippy.yml @@ -0,0 +1,22 @@ +clippy: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Set up Rust toolchain + uses: dtolnay/rust-toolchain@stable + with: + components: clippy + + - name: Cache Cargo registry and target + uses: actions/cache@v4 + with: + path: | + ~/.cargo/registry + target/ + key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} + restore-keys: | + ${{ runner.os }}-cargo- + + - name: Run Clippy + run: bash scripts/shell/linters/clippy.sh diff --git a/scripts/shell/linters/clippy.sh b/scripts/shell/linters/clippy.sh new file mode 100644 index 0000000..cad56a3 --- /dev/null +++ b/scripts/shell/linters/clippy.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env bash +set -euo pipefail + +if [[ ! -f "Cargo.toml" ]]; then + echo "::error::No Cargo.toml found" + exit 1 +fi + +echo "ℹ️ Running Clippy..." +cargo clippy --all-targets --all-features -- -D warnings \ + && echo "✅ Clippy passed" \ + || { echo "❌ Clippy found issues"; exit 1; } diff --git a/tests/linters/clippy.bats b/tests/linters/clippy.bats new file mode 100644 index 0000000..b670923 --- /dev/null +++ b/tests/linters/clippy.bats @@ -0,0 +1,47 @@ +#!/usr/bin/env bats + +load "../helpers/common" + +SCRIPT="$BATS_TEST_DIRNAME/../../scripts/shell/linters/clippy.sh" + +setup() { + setup_test_dir + mkdir -p "$TEST_DIR/bin" + export PATH="$TEST_DIR/bin:$PATH" +} + +teardown() { + teardown_test_dir +} + +make_cargo_stub() { + local exit_code="$1" + cat > "$TEST_DIR/bin/cargo" <