name: ShellCheck on: push: branches: [main] pull_request: branches: [main] permissions: contents: read jobs: shellcheck: name: Lint shell scripts runs-on: ubuntu-latest steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 - name: Install ShellCheck run: | sudo apt-get update sudo apt-get install -y shellcheck shellcheck --version - name: Run ShellCheck on ods shell scripts run: | # Find all .sh files under ods/ shfiles=$(find ods/ -name '*.sh' -type f) if [ -z "$shfiles" ]; then echo "No .sh files found under ods/" exit 0 fi echo "Found $(echo "$shfiles" | wc -l) shell scripts" echo "" # Run shellcheck: # -e SC1091 exclude "can't follow sourced files" # -e SC2034 exclude "unused variables" (many are used by sourced files) # -S warning treat warnings and above as reportable # shellcheck returns: # 0 = no issues # 1 = errors or warnings found # We fail the job only on error-severity issues by using -S error, # but still display warnings for visibility. # First pass: display all warnings and errors for visibility echo "=== ShellCheck results (warnings + errors) ===" echo "$shfiles" | xargs shellcheck \ --exclude=SC1091,SC2034 \ --severity=warning \ --format=gcc \ || true echo "" echo "=== Checking for error-severity issues (will fail if found) ===" # Second pass: fail only on error severity echo "$shfiles" | xargs shellcheck \ --exclude=SC1091,SC2034 \ --severity=error - name: Regression guard - no http://localhost in shell scripts run: | # IPv6 ::1 resolution can hang on macOS; always use 127.0.0.1 in # shell scripts. Excludes: demo-offline.sh (echo'd documentation, # never executed) and test-extension-audit.sh (heredoc compose YAML # fixtures with container-internal localhost). # Note: extensionless scripts (e.g. ods-cli) are not scanned by # this glob; coverage is limited to *.sh / *.bash. ods-cli's # localhost sites were handled by the earlier localhost-to-127.0.0.1 sweep. matches=$(find ods -type f \( -name '*.sh' -o -name '*.bash' \) \ ! -path 'ods/scripts/demo-offline.sh' \ ! -path 'ods/tests/test-extension-audit.sh' \ -exec grep -nE 'curl[^|]*http://localhost:' {} + || true) if [ -n "$matches" ]; then echo "::error::curl http://localhost: detected; use 127.0.0.1 (IPv6 ::1 resolution can hang on macOS):" echo "$matches" exit 1 fi