Update README.md #630
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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: 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 | |
| - name: prompt-injection-firewall | |
| type: ruff | |
| path: PROJECTS/beginner/prompt-injection-firewall | |
| # 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 | |
| - name: prompt-injection-firewall-frontend | |
| type: frontend | |
| path: PROJECTS/beginner/prompt-injection-firewall/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' | |
| # Ruff is pinned to the rev in .pre-commit-config.yaml rather than | |
| # hardcoded here, so bumping the hook bumps CI in the same commit. | |
| # An unpinned `pip install ruff` silently adopts newly-stabilized | |
| # rules and fails code the local hook just passed. | |
| - name: Resolve pinned ruff version | |
| if: matrix.type == 'ruff' | |
| id: ruff_version | |
| run: | | |
| version=$(grep -A1 'astral-sh/ruff-pre-commit' \ | |
| "$GITHUB_WORKSPACE/.pre-commit-config.yaml" \ | |
| | grep -oP 'rev:\s*v\K[0-9]+\.[0-9]+\.[0-9]+') | |
| if [[ -z "$version" ]]; then | |
| echo "Could not resolve ruff rev from .pre-commit-config.yaml" | |
| exit 1 | |
| fi | |
| echo "Pinned ruff version: $version" | |
| echo "version=$version" >> "$GITHUB_OUTPUT" | |
| - name: Install ruff | |
| if: matrix.type == 'ruff' | |
| run: pip install "ruff==${{ steps.ruff_version.outputs.version }}" | |
| # 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" |