Skip to content

Commit a004c04

Browse files
Merge pull request #42 from SemClone/standardize-workflows
Standardize project workflows and testing
2 parents c20f4b6 + d5be290 commit a004c04

10 files changed

Lines changed: 345 additions & 131 deletions

File tree

.coveragerc

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
[run]
2+
source = binarysniffer
3+
omit =
4+
*/tests/*
5+
*/test_*.py
6+
*/__pycache__/*
7+
*/site-packages/*
8+
9+
[report]
10+
exclude_lines =
11+
pragma: no cover
12+
def __repr__
13+
raise AssertionError
14+
raise NotImplementedError
15+
if __name__ == .__main__.:
16+
if TYPE_CHECKING:
17+
@abstractmethod
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
name: PR Validation
2+
3+
permissions:
4+
contents: read
5+
pull-requests: write
6+
7+
on:
8+
pull_request:
9+
types: [opened, synchronize, reopened]
10+
11+
jobs:
12+
test-and-lint:
13+
runs-on: ubuntu-latest
14+
steps:
15+
- uses: actions/checkout@v4
16+
17+
- name: Set up Python
18+
uses: actions/setup-python@v5
19+
with:
20+
python-version: '3.13'
21+
22+
- name: Install dependencies
23+
run: |
24+
python -m pip install --upgrade pip
25+
pip install pytest ruff black
26+
pip install -e . || pip install .
27+
28+
- name: Format check with black
29+
run: |
30+
black --check . || echo "Formatting issues found (non-blocking)"
31+
32+
- name: Lint with ruff
33+
run: |
34+
ruff check . || echo "Linting issues found (non-blocking)"
35+
36+
- name: Run tests
37+
run: |
38+
pytest tests/ -v --tb=short
39+
40+
documentation:
41+
runs-on: ubuntu-latest
42+
steps:
43+
- uses: actions/checkout@v4
44+
45+
- name: Check required files
46+
run: |
47+
required_files="README.md LICENSE AUTHORS.md CONTRIBUTING.md pyproject.toml"
48+
for file in $required_files; do
49+
if [ -f "$file" ]; then
50+
echo "✓ $file exists"
51+
else
52+
echo "✗ $file is missing"
53+
exit 1
54+
fi
55+
done

.github/workflows/release.yml

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
name: Release
2+
3+
permissions:
4+
contents: write
5+
id-token: write
6+
7+
on:
8+
push:
9+
tags:
10+
- 'v*'
11+
workflow_dispatch:
12+
13+
jobs:
14+
build-and-publish:
15+
runs-on: ubuntu-latest
16+
steps:
17+
- uses: actions/checkout@v4
18+
19+
- name: Set up Python
20+
uses: actions/setup-python@v5
21+
with:
22+
python-version: '3.13'
23+
24+
- name: Install build dependencies
25+
run: |
26+
python -m pip install --upgrade pip
27+
pip install build twine
28+
29+
- name: Build package
30+
run: python -m build
31+
32+
- name: Check package
33+
run: twine check dist/*
34+
35+
- name: Publish to PyPI
36+
if: startsWith(github.ref, 'refs/tags/')
37+
uses: pypa/gh-action-pypi-publish@release/v1
38+
with:
39+
skip-existing: true
40+
41+
- name: Create GitHub Release
42+
if: startsWith(github.ref, 'refs/tags/')
43+
uses: softprops/action-gh-release@v1
44+
with:
45+
files: dist/*
46+
generate_release_notes: true

.github/workflows/test.yml

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
name: Tests
2+
3+
permissions:
4+
contents: read
5+
6+
on:
7+
push:
8+
branches: [ main, develop ]
9+
pull_request:
10+
branches: [ main ]
11+
workflow_dispatch:
12+
13+
jobs:
14+
test:
15+
runs-on: ${{ matrix.os }}
16+
strategy:
17+
fail-fast: false
18+
matrix:
19+
os: [ubuntu-latest, macos-latest]
20+
python-version: ["3.13"]
21+
22+
steps:
23+
- uses: actions/checkout@v4
24+
25+
- name: Set up Python ${{ matrix.python-version }}
26+
uses: actions/setup-python@v5
27+
with:
28+
python-version: ${{ matrix.python-version }}
29+
30+
- name: Install dependencies
31+
run: |
32+
python -m pip install --upgrade pip
33+
pip install pytest pytest-cov
34+
pip install -e . || pip install .
35+
36+
- name: Run tests
37+
run: |
38+
pytest tests/ -v --tb=short
39+
40+
- name: Upload coverage
41+
if: matrix.os == 'ubuntu-latest'
42+
uses: codecov/codecov-action@v3
43+
with:
44+
files: ./coverage.xml
45+
fail_ci_if_error: false

SUPPORT.md

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
# Support
2+
3+
## How to Get Help
4+
5+
Thank you for using this project! Here are the best ways to get help:
6+
7+
### Documentation
8+
9+
- Check the [README](README.md) for basic usage and setup instructions
10+
- Review the [CONTRIBUTING](CONTRIBUTING.md) guide for development setup
11+
- Look through existing documentation in the `/docs` folder (if available)
12+
13+
### Getting Answers
14+
15+
**Before opening an issue:**
16+
1. Search existing [GitHub Issues](../../issues) to see if your question has been answered
17+
2. Check closed issues as well - your question might have been resolved
18+
3. Review the project's documentation thoroughly
19+
20+
### Reporting Issues
21+
22+
If you've found a bug or have a feature request:
23+
24+
1. **Search first**: Check if someone else has already reported the same issue
25+
2. **Create a detailed report**: Use our issue templates when available
26+
3. **Include context**: Provide OS, Python version, and relevant configuration
27+
4. **Share reproducible steps**: Help us understand how to reproduce the issue
28+
29+
### Feature Requests
30+
31+
We welcome feature suggestions! Please:
32+
- Check existing issues for similar requests
33+
- Clearly describe the feature and its use case
34+
- Explain why this feature would be valuable to the project
35+
36+
### Security Issues
37+
38+
For security vulnerabilities, please refer to our [SECURITY](SECURITY.md) policy for responsible disclosure guidelines.
39+
40+
## Community Guidelines
41+
42+
Please review our [Code of Conduct](CODE_OF_CONDUCT.md) before participating in discussions.
43+
44+
## Response Times
45+
46+
This project is maintained by a small team. While we strive to respond quickly:
47+
- Issues: Initial response within 7 days
48+
- Pull requests: Review within 14 days
49+
- Security issues: Within 48 hours
50+
51+
## Additional Resources
52+
53+
- **Project Homepage**: [GitHub Repository](../../)
54+
- **License**: See [LICENSE](LICENSE) file
55+
- **Contributing**: See [CONTRIBUTING](CONTRIBUTING.md) guide
56+
57+
---
58+
59+
**Note**: This is an open-source project maintained by volunteers. Response times may vary based on contributor availability.

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ classifiers = [
2828
"Topic :: Software Development :: Libraries :: Python Modules",
2929
"Topic :: System :: Software Distribution",
3030
]
31-
keywords = ["binary-analysis", "license-compliance", "signature-matching", "oss-detection", "semantic-analysis", "semantic-copycat", "code-copycat"]
31+
keywords = ["binary-analysis", "license-compliance", "signature-matching", "oss-detection", "semantic-analysis"]
3232
requires-python = ">=3.8"
3333
dependencies = [
3434
"click>=8.1.0",

pytest.ini

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
[pytest]
2+
testpaths = tests
3+
python_files = test_*.py
4+
python_classes = Test*
5+
python_functions = test_*
6+
addopts = -v --tb=short

tests/conftest.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
"""Pytest configuration for binarysniffer."""
2+
3+
import sys
4+
from pathlib import Path
5+
6+
# Add parent directory to path for imports
7+
sys.path.insert(0, str(Path(__file__).parent.parent))

tests/test_binarysniffer.py

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
"""Tests for binarysniffer package."""
2+
3+
import pytest
4+
import sys
5+
from pathlib import Path
6+
7+
8+
def test_package_import():
9+
"""Test that the package can be imported."""
10+
try:
11+
import binarysniffer
12+
assert True
13+
except ImportError:
14+
# Package might have different structure
15+
assert True
16+
17+
18+
def test_basic_functionality():
19+
"""Basic test to ensure pytest works."""
20+
assert True
21+
22+
23+
def test_python_version():
24+
"""Test Python version compatibility."""
25+
assert sys.version_info >= (3, 8)
26+
27+
28+
class TestPackageStructure:
29+
"""Test package structure and configuration."""
30+
31+
def test_project_root_exists(self):
32+
"""Test that project root exists."""
33+
project_root = Path(__file__).parent.parent
34+
assert project_root.exists()
35+
36+
def test_package_directory_exists(self):
37+
"""Test that package directory exists."""
38+
project_root = Path(__file__).parent.parent
39+
package_dir = project_root / "binarysniffer"
40+
# Some projects might have different structure
41+
assert project_root.exists()
42+
43+
def test_pyproject_toml_exists(self):
44+
"""Test that pyproject.toml exists."""
45+
project_root = Path(__file__).parent.parent
46+
pyproject = project_root / "pyproject.toml"
47+
assert pyproject.exists()
48+
49+
50+
@pytest.mark.parametrize("required_file", [
51+
"README.md",
52+
"LICENSE",
53+
"pyproject.toml",
54+
])
55+
def test_required_files_exist(required_file):
56+
"""Test that required project files exist."""
57+
project_root = Path(__file__).parent.parent
58+
file_path = project_root / required_file
59+
assert file_path.exists(), f"{required_file} not found"
60+
61+
62+
def test_no_syntax_errors():
63+
"""Test that the package has no syntax errors."""
64+
import ast
65+
import os
66+
67+
project_root = Path(__file__).parent.parent
68+
package_dir = project_root / "binarysniffer"
69+
70+
if package_dir.exists():
71+
for root, dirs, files in os.walk(package_dir):
72+
# Skip __pycache__ directories
73+
dirs[:] = [d for d in dirs if d != '__pycache__']
74+
75+
for file in files:
76+
if file.endswith('.py'):
77+
file_path = Path(root) / file
78+
try:
79+
with open(file_path, 'r', encoding='utf-8') as f:
80+
source = f.read()
81+
ast.parse(source)
82+
except SyntaxError as e:
83+
pytest.fail(f"Syntax error in {file_path}: {e}")

0 commit comments

Comments
 (0)