Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1508,6 +1508,18 @@ docker run --rm \

---

## 📚 **Documentation**

- **[Quick Start Guide](#-quick-start-guide)** - Get up and running in minutes
- **[Installation Guide](#-installation-guide)** - Detailed installation instructions
- **[Usage Examples](#-usage-examples)** - Common use cases and examples
- **[Docker Guide](DOCKER.md)** - Containerized deployment and usage
- **[CI/CD Integration Guide](CI_INTEGRATION.md)** - GitLab CI, GitHub Actions, and Jenkins integration
- **[Security Findings](docs/security-findings.md)** - Understanding security analysis results
- **[Contributing Guidelines](CONTRIBUTING.md)** - How to contribute to the project

---

**🦅 EndPointHawk - Securing APIs, one route at a time**

*Built with ❤️ by the security community*
52 changes: 50 additions & 2 deletions endpointhawk_core/endpointhawk.py
Original file line number Diff line number Diff line change
Expand Up @@ -1830,8 +1830,23 @@ async def _export_comparison_results(result: ComparisonResult, output_dir: str,
output_path = Path(output_dir)
output_path.mkdir(parents=True, exist_ok=True)

timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
filename = f"directory_comparison_{timestamp}.{output_format}"
# Check if we're in a CI environment and use consistent filename
ci_env = any([
os.environ.get('CI', '').lower() == 'true',
os.environ.get('GITLAB_CI', '').lower() == 'true',
os.environ.get('GITHUB_ACTIONS', '').lower() == 'true',
os.environ.get('JENKINS_URL'),
os.environ.get('BUILD_ID')
])

if ci_env:
# Use consistent filename for CI environments
filename = f"endpointhawk_comparison.{output_format}"
else:
# Use timestamped filename for local development
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
filename = f"directory_comparison_{timestamp}.{output_format}"

file_path = output_path / filename

try:
Expand Down Expand Up @@ -2040,6 +2055,39 @@ async def _run_git_comparison(config: ScanConfig, comparison_config: ComparisonC
console.print_exception()
raise

def _get_expected_output_filename(output_format: str = 'json', is_comparison: bool = False) -> str:
"""
Get the expected output filename for CI environments.

Args:
output_format: Output format (json, csv, html, etc.)
is_comparison: Whether this is a comparison report

Returns:
Expected filename
"""
# Check if we're in a CI environment
ci_env = any([
os.environ.get('CI', '').lower() == 'true',
os.environ.get('GITLAB_CI', '').lower() == 'true',
os.environ.get('GITHUB_ACTIONS', '').lower() == 'true',
os.environ.get('JENKINS_URL'),
os.environ.get('BUILD_ID')
])

if ci_env:
if is_comparison:
return f"endpointhawk_comparison.{output_format}"
else:
return f"endpointhawk_report.{output_format}"
else:
# For local development, use timestamped names
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
if is_comparison:
return f"directory_comparison_{timestamp}.{output_format}"
else:
return f"endpointhawk_report_{timestamp}.{output_format}"

@click.command()
@click.option('--repo-path', help='Path to repository to scan')
@click.option('--output-dir', default='./reports',
Expand Down
34 changes: 34 additions & 0 deletions utils/git_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,40 @@ def __init__(self, repo_path: str):
"""
self.repo_path = Path(repo_path).resolve()
self._is_git_repo = self._validate_git_repo()

# Configure Git for CI environments if needed
if self._is_git_repo:
self._configure_git_for_ci()

def _configure_git_for_ci(self):
"""Configure Git to handle CI environment ownership issues"""
try:
# Check if we're in a CI environment
ci_env = any([
os.environ.get('CI', '').lower() == 'true',
os.environ.get('GITLAB_CI', '').lower() == 'true',
os.environ.get('GITHUB_ACTIONS', '').lower() == 'true',
os.environ.get('JENKINS_URL'),
os.environ.get('BUILD_ID')
])

if ci_env:
# Add repository to safe.directory to handle ownership issues
repo_str = str(self.repo_path)
result = subprocess.run(
['git', 'config', '--global', '--add', 'safe.directory', repo_str],
capture_output=True,
text=True,
timeout=10
)

if result.returncode == 0:
logger.debug(f"Added {repo_str} to Git safe.directory for CI environment")
else:
logger.warning(f"Failed to add {repo_str} to Git safe.directory: {result.stderr}")

except Exception as e:
logger.warning(f"Error configuring Git for CI environment: {e}")

def _validate_git_repo(self) -> bool:
"""Validate that the path is a git repository"""
Expand Down