Cybersecurity-Projects/.github/workflows/lint.yml

925 lines
30 KiB
YAML

name: Lint & Type Check
on:
push:
branches: [ 'main' ]
pull_request:
branches: [ '*' ]
workflow_dispatch:
jobs:
lint:
name: Lint ${{ matrix.name }}
runs-on: ubuntu-latest
permissions:
contents: read
strategy:
fail-fast: false
matrix:
include:
# Python (ruff) - Beginner
- name: caesar-cipher
type: ruff
path: PROJECTS/beginner/caesar-cipher
- name: keylogger
type: ruff
path: PROJECTS/beginner/keylogger
- name: dns-lookup
type: ruff
path: PROJECTS/beginner/dns-lookup
- name: metadata-scrubber-tool
type: ruff
path: PROJECTS/beginner/metadata-scrubber-tool
- name: network-traffic-analyzer
type: ruff
path: PROJECTS/beginner/network-traffic-analyzer/python
- name: base64-tool
type: ruff
path: PROJECTS/beginner/base64-tool
- name: c2-beacon-backend
type: ruff
path: PROJECTS/beginner/c2-beacon/backend
# Python (ruff) - Intermediate
- name: api-security-scanner-backend
type: ruff
path: PROJECTS/intermediate/api-security-scanner/backend
- name: siem-dashboard-backend
type: ruff
path: PROJECTS/intermediate/siem-dashboard/backend
# Python (ruff) - Advanced
- name: bug-bounty-platform-backend
type: ruff
path: PROJECTS/advanced/bug-bounty-platform/backend
- name: encrypted-p2p-chat-backend
type: ruff
path: PROJECTS/advanced/encrypted-p2p-chat/backend
- name: api-rate-limiter
type: ruff
path: PROJECTS/advanced/api-rate-limiter
- name: ai-threat-detection-backend
type: ruff
path: PROJECTS/advanced/ai-threat-detection/backend
- name: linux-ebpf-security-tracer
type: ruff
path: PROJECTS/beginner/linux-ebpf-security-tracer
- name: dlp-scanner
type: ruff
path: PROJECTS/intermediate/dlp-scanner
# Python (ruff) - Foundations
- name: hash-identifier
type: ruff
path: PROJECTS/foundations/hash-identifier
- name: http-headers-scanner
type: ruff
path: PROJECTS/foundations/http-headers-scanner
- name: password-manager
type: ruff
path: PROJECTS/foundations/password-manager
# Biome (frontend)
- name: bug-bounty-platform-frontend
type: biome
path: PROJECTS/advanced/bug-bounty-platform/frontend
- name: c2-beacon-frontend
type: biome
path: PROJECTS/beginner/c2-beacon/frontend
- name: api-security-scanner-frontend
type: biome
path: PROJECTS/intermediate/api-security-scanner/frontend
- name: siem-dashboard-frontend
type: biome
path: PROJECTS/intermediate/siem-dashboard/frontend
- name: encrypted-p2p-chat-frontend
type: biome
path: PROJECTS/advanced/encrypted-p2p-chat/frontend
- name: canary-token-generator-frontend
type: biome
path: PROJECTS/beginner/canary-token-generator/frontend
- name: ai-threat-detection-frontend
type: biome
path: PROJECTS/advanced/ai-threat-detection/frontend
- name: binary-analysis-tool-frontend
type: biome
path: PROJECTS/intermediate/binary-analysis-tool/frontend
- name: honeypot-network-frontend
type: biome
path: PROJECTS/advanced/honeypot-network/frontend
- name: monitor-the-situation-dashboard-frontend
type: biome
path: PROJECTS/advanced/monitor-the-situation-dashboard/frontend
# Frontend (biome + stylelint + tsc)
- name: ja3-ja4-tls-fingerprinting-frontend
type: frontend
path: PROJECTS/intermediate/ja3-ja4-tls-fingerprinting/frontend
# Go
- name: simple-vulnerability-scanner
type: go
path: PROJECTS/beginner/simple-vulnerability-scanner
- name: docker-security-audit
type: go
path: PROJECTS/intermediate/docker-security-audit
- name: secrets-scanner
type: go
path: PROJECTS/intermediate/secrets-scanner
- name: canary-token-generator-backend
type: go
path: PROJECTS/beginner/canary-token-generator/backend
- name: systemd-persistence-scanner
type: go
path: PROJECTS/beginner/systemd-persistence-scanner
- name: sbom-generator-vulnerability-matcher
type: go
path: PROJECTS/intermediate/sbom-generator-vulnerability-matcher
- name: honeypot-network
type: go
path: PROJECTS/advanced/honeypot-network
- name: monitor-the-situation-dashboard-backend
type: go
path: PROJECTS/advanced/monitor-the-situation-dashboard/backend
# Nim
- name: credential-enumeration
type: nim
path: PROJECTS/intermediate/credential-enumeration
# Rust
- name: binary-analysis-tool-backend
type: rust
path: PROJECTS/intermediate/binary-analysis-tool/backend
- name: ja3-ja4-tls-fingerprinting
type: rust
path: PROJECTS/intermediate/ja3-ja4-tls-fingerprinting
# Crystal
- name: credential-rotation-enforcer
type: crystal
path: PROJECTS/intermediate/credential-rotation-enforcer
# V (Vlang)
- name: firewall-rule-engine
type: v
path: PROJECTS/beginner/firewall-rule-engine
# C++
- name: hash-cracker
type: cpp
path: PROJECTS/beginner/hash-cracker
- name: simple-port-scanner
type: cpp
path: PROJECTS/beginner/simple-port-scanner
- name: network-traffic-analyzer-cpp
type: cpp
path: PROJECTS/beginner/network-traffic-analyzer/cpp
# Bash (shellcheck)
- name: linux-cis-hardening-auditor
type: bash
path: PROJECTS/beginner/linux-cis-hardening-auditor
defaults:
run:
working-directory: ${{ matrix.path }}
steps:
- name: Checkout code
uses: actions/checkout@v4
# Ruff Setup
- name: Set up Python
if: matrix.type == 'ruff'
uses: actions/setup-python@v5
with:
python-version: '3.12'
- name: Install ruff
if: matrix.type == 'ruff'
run: pip install ruff
# Biome / Frontend Setup
- name: Setup Node.js
if: matrix.type == 'biome' || matrix.type == 'frontend'
uses: actions/setup-node@v4
with:
node-version: '22'
- name: Setup pnpm
if: matrix.type == 'biome' || matrix.type == 'frontend'
uses: pnpm/action-setup@v4
with:
version: 10
- name: Cache pnpm store
if: matrix.type == 'biome' || matrix.type == 'frontend'
uses: actions/cache@v4
with:
path: ~/.local/share/pnpm/store/v10
key: ${{ runner.os }}-pnpm-${{ matrix.name }}-${{ hashFiles(format('{0}/pnpm-lock.yaml', matrix.path)) }}
restore-keys: |
${{ runner.os }}-pnpm-${{ matrix.name }}-
${{ runner.os }}-pnpm-
- name: Install frontend dependencies
if: matrix.type == 'biome' || matrix.type == 'frontend'
run: pnpm install --frozen-lockfile
# Go Setup
- name: Setup Go
if: matrix.type == 'go'
uses: actions/setup-go@v5
with:
go-version-file: ${{ matrix.path }}/go.mod
cache-dependency-path: ${{ matrix.path }}/go.sum
- name: Install golangci-lint
if: matrix.type == 'go'
run: go install github.com/golangci/golangci-lint/v2/cmd/golangci-lint@v2.10.1
# Nim Setup
- name: Setup Nim
if: matrix.type == 'nim'
run: |
curl https://nim-lang.org/choosenim/init.sh -sSf | bash -s -- -y
echo "$HOME/.nimble/bin" >> $GITHUB_PATH
- name: Install nph
if: matrix.type == 'nim'
run: nimble install -y nph
# Rust Setup (pinned to match locally-verified clippy version)
- name: Install Rust 1.92.0
if: matrix.type == 'rust'
uses: dtolnay/rust-toolchain@1.92.0
with:
components: rustfmt, clippy
- name: Cache Cargo registry and target
if: matrix.type == 'rust'
uses: Swatinem/rust-cache@v2
with:
workspaces: "${{ matrix.path }} -> target"
# Crystal Setup
- name: Install libyaml-dev (ameba dep)
if: matrix.type == 'crystal'
run: |
sudo apt-get update -qq
sudo apt-get install -y libyaml-dev
- name: Install Crystal
if: matrix.type == 'crystal'
uses: crystal-lang/install-crystal@v1
with:
crystal: 1.20.0
- name: Cache shards
if: matrix.type == 'crystal'
uses: actions/cache@v4
with:
path: ${{ matrix.path }}/lib
key: ${{ runner.os }}-shards-${{ matrix.name }}-${{ hashFiles(format('{0}/shard.lock', matrix.path)) }}
restore-keys: |
${{ runner.os }}-shards-${{ matrix.name }}-
${{ runner.os }}-shards-
- name: Install shards
if: matrix.type == 'crystal'
run: shards install
- name: Build ameba binary
if: matrix.type == 'crystal'
run: |
mkdir -p bin
crystal build lib/ameba/bin/ameba.cr -o bin/ameba
# V (Vlang) Setup (no check-latest — master drift breaks fmt parity)
- name: Install V
if: matrix.type == 'v'
uses: vlang/setup-v@v1.4
# C++ Setup (pinned clang-format via PyPI wheel — apt patch versions drift)
- name: Install clang-format and cppcheck
if: matrix.type == 'cpp'
run: |
sudo apt-get update -qq
sudo apt-get install -y cppcheck python3-pip
pip install --user --break-system-packages clang-format==19.1.7
echo "$HOME/.local/bin" >> $GITHUB_PATH
# Bash Setup (shellcheck pre-installed on ubuntu-latest, but ensure latest)
- name: Install shellcheck
if: matrix.type == 'bash'
run: |
sudo apt-get update -qq
sudo apt-get install -y shellcheck
# Ruff Linting
- name: Run ruff
if: matrix.type == 'ruff'
id: ruff
run: |
echo "Running ruff check..."
if ruff check . > ruff-output.txt 2>&1; then
echo "RUFF_PASSED=true" >> $GITHUB_ENV
echo "No ruff errors found!"
else
echo "RUFF_PASSED=false" >> $GITHUB_ENV
echo "Ruff found issues"
fi
cat ruff-output.txt
continue-on-error: true
# Biome Linting
- name: Run Biome
if: matrix.type == 'biome'
id: biome
run: |
echo "Running Biome check..."
if npx @biomejs/biome check . > biome-output.txt 2>&1; then
echo "BIOME_PASSED=true" >> $GITHUB_ENV
echo "No Biome errors found!"
else
echo "BIOME_PASSED=false" >> $GITHUB_ENV
echo "Biome found issues!"
fi
cat biome-output.txt
continue-on-error: true
# Frontend Linting (biome + stylelint + tsc)
- name: Run Biome, Stylelint, and tsc
if: matrix.type == 'frontend'
id: frontend
run: |
FRONTEND_OK=true
echo "Running Biome check..."
if pnpm biome check . > frontend-output.txt 2>&1; then
echo "biome: no issues"
else
FRONTEND_OK=false
echo "biome: issues found"
fi
echo "Running Stylelint..."
if pnpm stylelint "**/*.scss" >> frontend-output.txt 2>&1; then
echo "stylelint: no issues"
else
FRONTEND_OK=false
echo "stylelint: issues found"
fi
echo "Running tsc --noEmit..."
if pnpm tsc --noEmit >> frontend-output.txt 2>&1; then
echo "tsc: no issues"
else
FRONTEND_OK=false
echo "tsc: type errors found"
fi
if [[ "$FRONTEND_OK" == "true" ]]; then
echo "FRONTEND_PASSED=true" >> $GITHUB_ENV
else
echo "FRONTEND_PASSED=false" >> $GITHUB_ENV
fi
cat frontend-output.txt
continue-on-error: true
# Go Linting
- name: Run golangci-lint
if: matrix.type == 'go'
id: golangci
run: |
echo "Running golangci-lint..."
if golangci-lint run > golangci-output.txt 2>&1; then
echo "GOLANGCI_PASSED=true" >> $GITHUB_ENV
echo "No golangci-lint errors found!"
else
echo "GOLANGCI_PASSED=false" >> $GITHUB_ENV
echo "golangci-lint found issues!"
fi
cat golangci-output.txt
continue-on-error: true
# Nim Linting
- name: Run nph and nim check
if: matrix.type == 'nim'
id: nim
run: |
echo "Running nph format check..."
NPH_OK=true
NIM_OK=true
if nph --check src/ > nim-output.txt 2>&1; then
echo "nph: no formatting issues"
else
NPH_OK=false
echo "nph: formatting issues found"
fi
echo "Running nim check..."
if nim check src/harvester.nim >> nim-output.txt 2>&1; then
echo "nim check: passed"
else
NIM_OK=false
echo "nim check: failed"
fi
if [[ "$NPH_OK" == "true" && "$NIM_OK" == "true" ]]; then
echo "NIM_PASSED=true" >> $GITHUB_ENV
echo "All Nim checks passed!"
else
echo "NIM_PASSED=false" >> $GITHUB_ENV
echo "Nim checks found issues"
fi
cat nim-output.txt
continue-on-error: true
# Rust Linting
- name: Run cargo fmt and clippy
if: matrix.type == 'rust'
id: rust
run: |
RUST_OK=true
echo "Running cargo fmt --check..."
if cargo fmt -- --check > rust-output.txt 2>&1; then
echo "cargo fmt: no issues"
else
RUST_OK=false
echo "cargo fmt: formatting issues found"
fi
echo "Running cargo clippy..."
if cargo clippy --all-targets --all-features -- -D warnings >> rust-output.txt 2>&1; then
echo "cargo clippy: no issues"
else
RUST_OK=false
echo "cargo clippy: issues found"
fi
if [[ "$RUST_OK" == "true" ]]; then
echo "RUST_PASSED=true" >> $GITHUB_ENV
else
echo "RUST_PASSED=false" >> $GITHUB_ENV
fi
cat rust-output.txt
continue-on-error: true
# Crystal Linting
- name: Run crystal format + ameba + compile check
if: matrix.type == 'crystal'
id: crystal
run: |
CRYSTAL_OK=true
echo "Running crystal tool format --check..."
if crystal tool format --check src/ spec/ > crystal-output.txt 2>&1; then
echo "crystal format: no issues"
else
CRYSTAL_OK=false
echo "crystal format: formatting issues found"
fi
echo "Running ameba..."
if bin/ameba src/ >> crystal-output.txt 2>&1; then
echo "ameba: no issues"
else
CRYSTAL_OK=false
echo "ameba: issues found"
fi
echo "Running crystal build --no-codegen..."
if crystal build --no-codegen src/cre.cr >> crystal-output.txt 2>&1; then
echo "crystal build: passed"
else
CRYSTAL_OK=false
echo "crystal build: failed"
fi
if [[ "$CRYSTAL_OK" == "true" ]]; then
echo "CRYSTAL_PASSED=true" >> $GITHUB_ENV
else
echo "CRYSTAL_PASSED=false" >> $GITHUB_ENV
fi
cat crystal-output.txt
continue-on-error: true
# V Linting (v fmt is advisory — formatter rules drift between V builds even
# within the same version string, making strict fmt parity impractical. v vet
# is stable across builds and remains the pass/fail gate.)
- name: Run v fmt (advisory) and v vet
if: matrix.type == 'v'
id: v
run: |
V_OK=true
echo "Running v fmt -diff src/ (advisory)..."
v fmt -diff src/ > v-output.txt 2>&1 || true
echo "Running v fmt -verify src/ (advisory)..."
if v fmt -verify src/ >> v-output.txt 2>&1; then
echo "v fmt: no issues"
else
echo "v fmt: formatting suggestions found (advisory — not failing the job)"
fi
echo "Running v vet src/..."
if v vet src/ >> v-output.txt 2>&1; then
echo "v vet: no issues"
else
V_OK=false
echo "v vet: issues found"
fi
if [[ "$V_OK" == "true" ]]; then
echo "V_PASSED=true" >> $GITHUB_ENV
else
echo "V_PASSED=false" >> $GITHUB_ENV
fi
cat v-output.txt
continue-on-error: true
# C++ Linting
- name: Run clang-format and cppcheck
if: matrix.type == 'cpp'
id: cpp
run: |
CPP_OK=true
echo "Running clang-format check..."
FILES=$(find . \( -path ./build -o -path ./cmake-build -o -path ./node_modules -o -path ./.git \) -prune -o \( -name '*.cpp' -o -name '*.hpp' -o -name '*.h' \) -print 2>/dev/null)
if [ -n "$FILES" ]; then
if echo "$FILES" | xargs clang-format --dry-run --Werror > cpp-output.txt 2>&1; then
echo "clang-format: no issues"
else
CPP_OK=false
echo "clang-format: formatting issues found"
fi
else
echo "clang-format: no C++ files found" > cpp-output.txt
fi
echo "Running cppcheck..."
if cppcheck --enable=warning,style,performance,portability --error-exitcode=1 --suppress=missingIncludeSystem --suppress=normalCheckLevelMaxBranches -i build -i cmake-build -q . >> cpp-output.txt 2>&1; then
echo "cppcheck: no issues"
else
CPP_OK=false
echo "cppcheck: issues found"
fi
if [[ "$CPP_OK" == "true" ]]; then
echo "CPP_PASSED=true" >> $GITHUB_ENV
else
echo "CPP_PASSED=false" >> $GITHUB_ENV
fi
cat cpp-output.txt
continue-on-error: true
# Bash Linting
- name: Run shellcheck
if: matrix.type == 'bash'
id: bash
run: |
echo "Running shellcheck..."
FILES=$(find . -name '*.sh' -not -path '*/.venv/*' -not -path '*/node_modules/*' 2>/dev/null || true)
if [ -z "$FILES" ]; then
echo "shellcheck: no .sh files found" > bash-output.txt
echo "BASH_PASSED=true" >> $GITHUB_ENV
elif echo "$FILES" | xargs shellcheck > bash-output.txt 2>&1; then
echo "BASH_PASSED=true" >> $GITHUB_ENV
echo "shellcheck: no issues"
else
echo "BASH_PASSED=false" >> $GITHUB_ENV
echo "shellcheck: issues found"
fi
cat bash-output.txt
continue-on-error: true
# Create Summary for Ruff
- name: Create Ruff Lint Summary
if: matrix.type == 'ruff'
run: |
{
echo "## Lint Results: ${{ matrix.name }}"
echo ''
if [[ "${{ env.RUFF_PASSED }}" == "true" ]]; then
echo '### Ruff: **Passed**'
echo 'No ruff issues found.'
else
echo '### Ruff: **Issues Found**'
echo '<details><summary>View ruff output</summary>'
echo ''
echo '```'
head -100 ruff-output.txt
echo '```'
echo '</details>'
fi
echo ''
if [[ "${{ env.RUFF_PASSED }}" == "true" ]]; then
echo '---'
echo '### All checks passed!'
else
echo '---'
echo '### Review the issues above'
fi
} >> $GITHUB_STEP_SUMMARY
# Create Summary for Biome
- name: Create Biome Lint Summary
if: matrix.type == 'biome'
run: |
{
echo "## Lint Results: ${{ matrix.name }}"
echo ''
if [[ "${{ env.BIOME_PASSED }}" == "true" ]]; then
echo '### Biome: **Passed**'
echo 'No Biome issues found.'
else
echo '### Biome: **Issues Found**'
echo '<details><summary>View Biome output</summary>'
echo ''
echo '```'
head -100 biome-output.txt
echo '```'
echo '</details>'
fi
echo ''
if [[ "${{ env.BIOME_PASSED }}" == "true" ]]; then
echo '---'
echo '### All checks passed!'
else
echo '---'
echo '### Review the issues above'
fi
} >> $GITHUB_STEP_SUMMARY
# Create Summary for Frontend
- name: Create Frontend Lint Summary
if: matrix.type == 'frontend'
run: |
{
echo "## Lint Results: ${{ matrix.name }}"
echo ''
if [[ "${{ env.FRONTEND_PASSED }}" == "true" ]]; then
echo '### Biome + Stylelint + tsc: **Passed**'
echo 'No frontend issues found.'
else
echo '### Biome + Stylelint + tsc: **Issues Found**'
echo '<details><summary>View output</summary>'
echo ''
echo '```'
head -100 frontend-output.txt
echo '```'
echo '</details>'
fi
echo ''
if [[ "${{ env.FRONTEND_PASSED }}" == "true" ]]; then
echo '---'
echo '### All checks passed!'
else
echo '---'
echo '### Review the issues above'
fi
} >> $GITHUB_STEP_SUMMARY
# Create Summary for Go
- name: Create Go Lint Summary
if: matrix.type == 'go'
run: |
{
echo "## Lint Results: ${{ matrix.name }}"
echo ''
if [[ "${{ env.GOLANGCI_PASSED }}" == "true" ]]; then
echo '### golangci-lint: **Passed**'
echo 'No golangci-lint issues found.'
else
echo '### golangci-lint: **Issues Found**'
echo '<details><summary>View golangci-lint output</summary>'
echo ''
echo '```'
head -100 golangci-output.txt
echo '```'
echo '</details>'
fi
echo ''
if [[ "${{ env.GOLANGCI_PASSED }}" == "true" ]]; then
echo '---'
echo '### All checks passed!'
else
echo '---'
echo '### Review the issues above'
fi
} >> $GITHUB_STEP_SUMMARY
# Create Summary for Nim
- name: Create Nim Lint Summary
if: matrix.type == 'nim'
run: |
{
echo "## Lint Results: ${{ matrix.name }}"
echo ''
if [[ "${{ env.NIM_PASSED }}" == "true" ]]; then
echo '### nph + nim check: **Passed**'
echo 'No Nim issues found.'
else
echo '### nph + nim check: **Issues Found**'
echo '<details><summary>View Nim output</summary>'
echo ''
echo '```'
head -100 nim-output.txt
echo '```'
echo '</details>'
fi
echo ''
if [[ "${{ env.NIM_PASSED }}" == "true" ]]; then
echo '---'
echo '### All checks passed!'
else
echo '---'
echo '### Review the issues above'
fi
} >> $GITHUB_STEP_SUMMARY
# Create Summary for Rust
- name: Create Rust Lint Summary
if: matrix.type == 'rust'
run: |
{
echo "## Lint Results: ${{ matrix.name }}"
echo ''
if [[ "${{ env.RUST_PASSED }}" == "true" ]]; then
echo '### cargo fmt + clippy: **Passed**'
echo 'No Rust issues found.'
else
echo '### cargo fmt + clippy: **Issues Found**'
echo '<details><summary>View output</summary>'
echo ''
echo '```'
head -100 rust-output.txt
echo '```'
echo '</details>'
fi
echo ''
if [[ "${{ env.RUST_PASSED }}" == "true" ]]; then
echo '---'
echo '### All checks passed!'
else
echo '---'
echo '### Review the issues above'
fi
} >> $GITHUB_STEP_SUMMARY
# Create Summary for Crystal
- name: Create Crystal Lint Summary
if: matrix.type == 'crystal'
run: |
{
echo "## Lint Results: ${{ matrix.name }}"
echo ''
if [[ "${{ env.CRYSTAL_PASSED }}" == "true" ]]; then
echo '### crystal format + ameba + build: **Passed**'
echo 'No Crystal issues found.'
else
echo '### crystal format + ameba + build: **Issues Found**'
echo '<details><summary>View output</summary>'
echo ''
echo '```'
head -100 crystal-output.txt
echo '```'
echo '</details>'
fi
echo ''
if [[ "${{ env.CRYSTAL_PASSED }}" == "true" ]]; then
echo '---'
echo '### All checks passed!'
else
echo '---'
echo '### Review the issues above'
fi
} >> $GITHUB_STEP_SUMMARY
# Create Summary for V
- name: Create V Lint Summary
if: matrix.type == 'v'
run: |
{
echo "## Lint Results: ${{ matrix.name }}"
echo ''
if [[ "${{ env.V_PASSED }}" == "true" ]]; then
echo '### v vet: **Passed** (v fmt advisory)'
echo 'No V vet issues found. See output for v fmt suggestions.'
else
echo '### v vet: **Issues Found**'
echo '<details><summary>View output</summary>'
echo ''
echo '```'
head -100 v-output.txt
echo '```'
echo '</details>'
fi
echo ''
if [[ "${{ env.V_PASSED }}" == "true" ]]; then
echo '---'
echo '### All checks passed!'
else
echo '---'
echo '### Review the issues above'
fi
} >> $GITHUB_STEP_SUMMARY
# Create Summary for C++
- name: Create C++ Lint Summary
if: matrix.type == 'cpp'
run: |
{
echo "## Lint Results: ${{ matrix.name }}"
echo ''
if [[ "${{ env.CPP_PASSED }}" == "true" ]]; then
echo '### clang-format + cppcheck: **Passed**'
echo 'No C++ issues found.'
else
echo '### clang-format + cppcheck: **Issues Found**'
echo '<details><summary>View output</summary>'
echo ''
echo '```'
head -100 cpp-output.txt
echo '```'
echo '</details>'
fi
echo ''
if [[ "${{ env.CPP_PASSED }}" == "true" ]]; then
echo '---'
echo '### All checks passed!'
else
echo '---'
echo '### Review the issues above'
fi
} >> $GITHUB_STEP_SUMMARY
# Create Summary for Bash
- name: Create Bash Lint Summary
if: matrix.type == 'bash'
run: |
{
echo "## Lint Results: ${{ matrix.name }}"
echo ''
if [[ "${{ env.BASH_PASSED }}" == "true" ]]; then
echo '### shellcheck: **Passed**'
echo 'No shell issues found.'
else
echo '### shellcheck: **Issues Found**'
echo '<details><summary>View output</summary>'
echo ''
echo '```'
head -100 bash-output.txt
echo '```'
echo '</details>'
fi
echo ''
if [[ "${{ env.BASH_PASSED }}" == "true" ]]; then
echo '---'
echo '### All checks passed!'
else
echo '---'
echo '### Review the issues above'
fi
} >> $GITHUB_STEP_SUMMARY
# Exit with proper status
- name: Check lint status
run: |
if [[ "${{ matrix.type }}" == "ruff" ]]; then
if [[ "${{ env.RUFF_PASSED }}" == "false" ]]; then
echo "Ruff lint checks failed"
exit 1
fi
elif [[ "${{ matrix.type }}" == "biome" ]]; then
if [[ "${{ env.BIOME_PASSED }}" == "false" ]]; then
echo "Biome lint checks failed"
exit 1
fi
elif [[ "${{ matrix.type }}" == "frontend" ]]; then
if [[ "${{ env.FRONTEND_PASSED }}" == "false" ]]; then
echo "Frontend lint checks failed"
exit 1
fi
elif [[ "${{ matrix.type }}" == "go" ]]; then
if [[ "${{ env.GOLANGCI_PASSED }}" == "false" ]]; then
echo "Go lint checks failed"
exit 1
fi
elif [[ "${{ matrix.type }}" == "nim" ]]; then
if [[ "${{ env.NIM_PASSED }}" == "false" ]]; then
echo "Nim lint checks failed"
exit 1
fi
elif [[ "${{ matrix.type }}" == "rust" ]]; then
if [[ "${{ env.RUST_PASSED }}" == "false" ]]; then
echo "Rust lint checks failed"
exit 1
fi
elif [[ "${{ matrix.type }}" == "crystal" ]]; then
if [[ "${{ env.CRYSTAL_PASSED }}" == "false" ]]; then
echo "Crystal lint checks failed"
exit 1
fi
elif [[ "${{ matrix.type }}" == "v" ]]; then
if [[ "${{ env.V_PASSED }}" == "false" ]]; then
echo "V lint checks failed"
exit 1
fi
elif [[ "${{ matrix.type }}" == "cpp" ]]; then
if [[ "${{ env.CPP_PASSED }}" == "false" ]]; then
echo "C++ lint checks failed"
exit 1
fi
elif [[ "${{ matrix.type }}" == "bash" ]]; then
if [[ "${{ env.BASH_PASSED }}" == "false" ]]; then
echo "Bash lint checks failed"
exit 1
fi
fi
echo "All lint checks passed"