Automated sanity checks and static analysis for multi-language projects.
An automated GitHub Actions workflow that performs static analysis and syntax validation on Pull Requests across multiple programming languages.
This repository contains a multi-language sanity check system that automatically validates code quality before merging. The workflow detects programming languages in Pull Request changes, runs language-specific linters and static analyzers, and reports results directly on the PR.
- Automatic Language Detection - Identifies programming languages from file extensions
- Conditional Tool Installation - Only installs tools for detected languages to optimize runtime
- Multi-Language Support - C/C++, JavaScript/TypeScript, Rust, Kotlin, Swift, Java, Dart/Flutter
- PR Integration - Posts detailed results as comments and applies status labels
- Merge Protection - Blocks PRs with failing checks from being merged
The workflow triggers on Pull Request events (opened, synchronize, reopened) and follows this process:
- Checkout - Retrieves the PR code
- File Detection - Identifies changed files by extension
- Language Detection - Determines which languages are present
- Tool Installation - Conditionally installs only required linting tools
- Static Analysis - Runs language-specific check scripts
- Results Reporting - Posts formatted comment on the PR
- Status Labeling - Applies
sanity-check-passedorsanity-check-failedlabel - Workflow Status - Fails the workflow if any checks fail
- Memory leak detection (malloc without free)
- Unsafe function usage (gets, strcpy)
- Uninitialized variables
- Include guard verification
- Buffer overflow detection
- console.log detection
- var keyword usage
- Loose equality (==) usage
- eval() usage
- debugger statements
- alert() usage
UNIT-TESTING-SANITY-CHECKS/ β βββ .vscode/ # Local VS Code settings (optional) β βββ scripts/ # Core automation scripts β βββ cpp-check.sh # Runs cppcheck for C/C++ code β βββ detect-language.sh # Detects programming language from PR file list β βββ flutter-check.sh # Placeholder for Flutter/Dart validation β βββ java-check.sh # Runs static checks for Java β βββ js-check.sh # Runs eslint for JavaScript β βββ kotlin-check.sh # Executes ktlint checks for Kotlin β βββ rust-check.sh # Runs cargo clippy for Rust β βββ swift-check.sh # Runs swiftlint for Swift β βββ run-checks.sh # Central script to invoke language-specific checks β βββ test-detection.sh # Validates detection and routing logic β βββ test-files/ # Sample test files per supported language β βββ cpp/ β β βββ good-example.cpp β βββ dart/ β β βββ sample.dart β βββ java/ β β βββ good-example.java β βββ javascript/ β β βββ good-example.js β βββ kotlin/ β β βββ sample.kt β βββ rust/ β β βββ good-example.rs β βββ swift/ β βββ good-example.swift β βββ branch_configuration.md # Notes on branch strategy and workflow testing βββ README.md # Documentation, setup steps, and usage guide '''
- Force unwrapping (!!)
- Force casting (as!)
- Class naming conventions (PascalCase)
- System.out.println usage
- Wildcard imports
- print() statement detection
- Class naming conventions
.github/workflows/sanity-check.yml # Main workflow configuration
scripts/detect-language.sh # Language detection logic
scripts/run-checks.sh # Check orchestration
scripts/cpp-check.sh # C/C++ analyzer
scripts/js-check.sh # JavaScript analyzer
scripts/rust-check.sh # Rust analyzer
scripts/kotlin-check.sh # Kotlin analyzer
scripts/swift-check.sh # Swift analyzer
scripts/java-check.sh # Java analyzer
scripts/flutter-check.sh # Dart/Flutter analyzer
test-files/ # Test cases for each language
README.md # This file
- Copy the
.github/workflows/sanity-check.ymlfile to your repository - Copy the
scripts/directory with all check scripts - Ensure scripts are executable:
chmod +x scripts/*.sh - Commit and push to enable the workflow
The test-files/ directory contains example files:
good-example.*- Code that passes all checksbad-example.*- Code with intentional violations
Create a Pull Request with these files to verify workflow functionality.
Passing Checks:
- Green checkmark in PR status
- Comment: "β Sanity Check PASSED"
- Label:
sanity-check-passed - PR can be merged
Failing Checks:
- Red X in PR status
- Comment with detailed error list
- Label:
sanity-check-failed - PR merge blocked
Key configuration points:
Trigger Events:
on:
pull_request:
types: [opened, synchronize, reopened]File Extensions:
files: |
**/*.c
**/*.cpp
**/*.js
# ... other extensionsTool Installation: Each language has a conditional installation step that only runs if that language is detected.
Each check script:
- Reads a list of files from
[language]_files.txt - Runs language-specific validation
- Exits with code 0 (pass) or 1 (fail)
- Outputs human-readable results to stdout
To modify checks:
Edit the relevant script in scripts/ directory. Each script uses simple pattern matching with grep for maximum portability.
To add new languages:
- Add file extensions to workflow YAML
- Create new check script:
scripts/[language]-check.sh - Add detection logic to
detect-language.sh - Add execution call in
run-checks.sh
The detect-language.sh script:
- Reads
changed_files.txtcontaining space-separated file paths - Uses
casestatement for extension matching - Creates
[language]_files.txtfor each detected language - Exports detection results to
detected_languages.env
The run-checks.sh script:
- Sources
detected_languages.env - Runs checks only for detected languages
- Aggregates results
- Exits with combined status code
The workflow uses GitHub Actions Script to:
- Read
check_results.txtcontaining all check output - Parse status from text markers
- Format as collapsible comment
- Apply appropriate label
- Set workflow exit status
GitHub Actions Environment:
- Ubuntu latest runner
- Node.js 18 (for JavaScript checks)
- Rust stable toolchain (for Rust checks)
- Java 17 (for Java checks)
- System packages: cppcheck (for C/C++ checks)
Permissions:
contents: read- Repository accesspull-requests: write- Comment and label managementissues: write- Label management
- Checks are syntax and style focused, not functional testing
- Some tools (ktlint, Flutter) require external downloads
- Swift checks require macOS runner for SwiftLint (currently uses pattern matching)
- No code coverage or complexity analysis
- Binary files are not analyzed
This workflow was developed and tested with:
- Multiple test PRs covering all supported languages
- Both passing and failing test cases
- Real-world code examples
- GitHub Actions workflow execution logs
Potential improvements:
- Integration with additional linters (ESLint, Pylint, etc.)
- Configurable rule severity levels
- Support for additional languages (Python, Go, etc.)
- Custom rule definitions per repository
- Performance metrics and check duration reporting
To add new checks or languages:
- Create check script following existing pattern
- Test with good and bad example files
- Update
detect-language.shfor file detection - Update
run-checks.shto execute new checks - Update this README with new language support
Your setup will be validated by:
- Creating a PR with test files
- Verifying workflow runs automatically
- Checking language detection works
- Confirming appropriate checks execute
- Validating PR comment is posted
- Ensuring correct label is applied
Task Complete When: A PR with intentionally bad code triggers the workflow, detects the issues, posts a detailed comment, applies the fail label, and blocks the merge.](https://github.com/Surabhis12/unit-testing-sanity-checks.git)