Skip to content

Commit 8d9719f

Browse files
Merge pull request #150 from contentstack/enh/dx-2780
Enh/dx 2780
2 parents 5988858 + 266702f commit 8d9719f

File tree

7 files changed

+346
-1
lines changed

7 files changed

+346
-1
lines changed

.husky/hooks/code-quality.sh

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
#!/usr/bin/env bash
2+
"""
3+
Code quality checking hook for Husky-style pre-commit setup.
4+
This hook runs Black, isort, flake8, and Bandit for code quality.
5+
"""
6+
7+
echo "🐍 Running Python code quality checks..."
8+
9+
# Function to check if a command exists
10+
command_exists() {
11+
command -v "$1" >/dev/null 2>&1
12+
}
13+
14+
# Check Black formatting
15+
echo " - Checking code formatting with Black..."
16+
if command_exists black; then
17+
if black --check --diff .; then
18+
echo " ✅ Black formatting check passed"
19+
else
20+
echo " ❌ Black formatting issues found"
21+
echo " 💡 Run 'black .' to fix formatting"
22+
exit 1
23+
fi
24+
else
25+
echo " ⚠️ Black not installed, skipping formatting check"
26+
echo " 💡 Install with: pip install black"
27+
fi
28+
29+
# Check isort import sorting
30+
echo " - Checking import sorting with isort..."
31+
if command_exists isort; then
32+
if isort --check-only --diff .; then
33+
echo " ✅ isort import sorting check passed"
34+
else
35+
echo " ❌ isort import sorting issues found"
36+
echo " 💡 Run 'isort .' to fix import sorting"
37+
exit 1
38+
fi
39+
else
40+
echo " ⚠️ isort not installed, skipping import sorting check"
41+
echo " 💡 Install with: pip install isort"
42+
fi
43+
44+
# Check flake8 linting
45+
echo " - Running linting with flake8..."
46+
if command_exists flake8; then
47+
if flake8 --max-line-length=88 --extend-ignore=E203,W503 .; then
48+
echo " ✅ flake8 linting check passed"
49+
else
50+
echo " ❌ flake8 linting issues found"
51+
echo " 💡 Fix the linting issues above"
52+
exit 1
53+
fi
54+
else
55+
echo " ⚠️ flake8 not installed, skipping linting check"
56+
echo " 💡 Install with: pip install flake8"
57+
fi
58+
59+
# Check Bandit security linting
60+
echo " - Running security linting with Bandit..."
61+
if command_exists bandit; then
62+
if bandit -r . -f json -o bandit-report.json; then
63+
echo " ✅ Bandit security linting check passed"
64+
else
65+
echo " ❌ Bandit found security issues"
66+
echo " 💡 Review bandit-report.json for details"
67+
exit 1
68+
fi
69+
else
70+
echo " ⚠️ Bandit not installed, skipping security linting"
71+
echo " 💡 Install with: pip install bandit"
72+
fi
73+
74+
echo "✅ All code quality checks passed!"

.husky/hooks/snyk-scan.py

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
#!/usr/bin/env python3
2+
"""
3+
Snyk security scanning hook for Husky-style pre-commit setup.
4+
This hook runs Snyk security scanning on Python dependencies.
5+
"""
6+
7+
import os
8+
import sys
9+
import subprocess
10+
import json
11+
from pathlib import Path
12+
13+
14+
def run_snyk_scan():
15+
"""Run Snyk security scan on Python dependencies."""
16+
17+
# Check if Snyk CLI is available
18+
try:
19+
subprocess.run(['snyk', '--version'], capture_output=True, check=True)
20+
except (subprocess.CalledProcessError, FileNotFoundError):
21+
print("❌ Snyk CLI not found. Please install it first:")
22+
print(" npm install -g snyk")
23+
print(" or visit: https://snyk.io/docs/using-snyk/")
24+
return 1
25+
26+
# Check if SNYK_TOKEN is set
27+
if not os.getenv('SNYK_TOKEN'):
28+
print("⚠️ SNYK_TOKEN environment variable not set.")
29+
print(" Please set it with: export SNYK_TOKEN=your_token")
30+
print(" You can get a token from: https://app.snyk.io/account")
31+
return 0 # Don't fail the commit, just warn
32+
33+
# Check for requirements.txt
34+
requirements_files = ['requirements.txt', 'setup.py']
35+
found_requirements = False
36+
37+
for req_file in requirements_files:
38+
if Path(req_file).exists():
39+
found_requirements = True
40+
break
41+
42+
if not found_requirements:
43+
print("⚠️ No requirements.txt or setup.py found. Skipping Snyk scan.")
44+
return 0
45+
46+
print("🔍 Running Snyk security scan...")
47+
48+
try:
49+
# Run Snyk test on Python dependencies
50+
result = subprocess.run([
51+
'snyk', 'test',
52+
'--severity-threshold=high',
53+
'--json'
54+
], capture_output=True, text=True, check=False)
55+
56+
if result.returncode == 0:
57+
print("✅ Snyk scan completed - no high severity vulnerabilities found")
58+
return 0
59+
else:
60+
# Parse JSON output to show vulnerabilities
61+
try:
62+
vulns = json.loads(result.stdout)
63+
if 'vulnerabilities' in vulns:
64+
print("❌ High severity vulnerabilities found:")
65+
for vuln in vulns['vulnerabilities']:
66+
if vuln.get('severity') == 'high':
67+
print(f" - {vuln.get('title', 'Unknown')} in {vuln.get('packageName', 'Unknown')}")
68+
print(f" CVSS Score: {vuln.get('cvssScore', 'N/A')}")
69+
print(f" More info: {vuln.get('url', 'N/A')}")
70+
print()
71+
72+
print("💡 To fix vulnerabilities, run: snyk wizard")
73+
return 1
74+
except json.JSONDecodeError:
75+
print("❌ Snyk scan failed with errors:")
76+
print(result.stderr)
77+
return 1
78+
79+
except Exception as e:
80+
print(f"❌ Error running Snyk scan: {e}")
81+
return 1
82+
83+
84+
if __name__ == '__main__':
85+
sys.exit(run_snyk_scan())

.husky/hooks/talisman-check.sh

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
#!/usr/bin/env bash
2+
"""
3+
Talisman secrets detection hook for Husky-style pre-commit setup.
4+
This hook runs Talisman to detect potential secrets in commits.
5+
"""
6+
7+
# Check if Talisman is available
8+
if ! command -v talisman &> /dev/null; then
9+
echo "❌ Talisman not found. Please install it first:"
10+
echo " # macOS"
11+
echo " brew install talisman"
12+
echo " # Linux"
13+
echo " curl -sL https://github.com/thoughtworks/talisman/releases/latest/download/talisman_linux_amd64 -o talisman"
14+
echo " chmod +x talisman"
15+
echo " sudo mv talisman /usr/local/bin/"
16+
exit 1
17+
fi
18+
19+
echo "🔐 Running Talisman secrets detection..."
20+
21+
# Run Talisman with pre-commit hook
22+
if talisman --githook pre-commit; then
23+
echo "✅ Talisman check passed - no secrets detected"
24+
exit 0
25+
else
26+
echo "❌ Talisman found potential secrets in your changes"
27+
echo ""
28+
echo "💡 To fix this:"
29+
echo "1. Review the files mentioned above"
30+
echo "2. Remove any actual secrets from your code"
31+
echo "3. If the file contains legitimate test data, add it to .talismanrc:"
32+
echo " talisman --checksum path/to/file"
33+
echo " # Then add the checksum to .talismanrc"
34+
exit 1
35+
fi

.husky/hooks/test-runner.sh

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
#!/usr/bin/env bash
2+
"""
3+
Test runner hook for Husky-style pre-push setup.
4+
This hook runs tests and coverage checks before pushing.
5+
"""
6+
7+
echo "🧪 Running tests and coverage checks..."
8+
9+
# Function to check if a command exists
10+
command_exists() {
11+
command -v "$1" >/dev/null 2>&1
12+
}
13+
14+
# Check if pytest is available
15+
if ! command_exists pytest; then
16+
echo "❌ pytest not found. Please install it first:"
17+
echo " pip install pytest pytest-cov"
18+
exit 1
19+
fi
20+
21+
# Run tests
22+
echo " - Running tests..."
23+
if pytest --html=tests/report/test-report.html; then
24+
echo " ✅ All tests passed"
25+
else
26+
echo " ❌ Tests failed. Please fix before pushing."
27+
exit 1
28+
fi
29+
30+
# Run coverage check
31+
echo " - Checking test coverage..."
32+
if command_exists pytest; then
33+
if pytest --cov=contentstack --cov-report=term-missing; then
34+
echo " ✅ Coverage check completed"
35+
else
36+
echo " ❌ Coverage check failed. Please improve test coverage."
37+
exit 1
38+
fi
39+
else
40+
echo " ⚠️ pytest-cov not installed, skipping coverage check"
41+
echo " 💡 Install with: pip install pytest-cov"
42+
fi
43+
44+
echo "✅ All test checks passed!"

.husky/pre-commit

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
#!/usr/bin/env sh
2+
# Pre-commit hook to run Talisman and Snyk scans, completing both before deciding to commit
3+
4+
# Function to check if a command exists
5+
command_exists() {
6+
command -v "$1" >/dev/null 2>&1
7+
}
8+
9+
# Check if Talisman is installed
10+
if ! command_exists talisman; then
11+
echo "Error: Talisman is not installed. Please install it and try again."
12+
exit 1
13+
fi
14+
15+
# Check if Snyk is installed
16+
if ! command_exists snyk; then
17+
echo "Error: Snyk is not installed. Please install it and try again."
18+
exit 1
19+
fi
20+
21+
# Allow bypassing the hook with an environment variable
22+
if [ "$SKIP_HOOK" = "1" ]; then
23+
echo "Skipping Talisman and Snyk scans (SKIP_HOOK=1)."
24+
exit 0
25+
fi
26+
27+
# Initialize variables to track scan results
28+
talisman_failed=false
29+
snyk_failed=false
30+
31+
# Run Talisman secret scan
32+
echo "Running Talisman secret scan..."
33+
talisman --githook pre-commit > talisman_output.log 2>&1
34+
talisman_exit_code=$?
35+
36+
if [ $talisman_exit_code -eq 0 ]; then
37+
echo "Talisman scan passed: No secrets found."
38+
else
39+
echo "Talisman scan failed (exit code $talisman_exit_code). See talisman_output.log for details."
40+
talisman_failed=true
41+
fi
42+
43+
# Run Snyk vulnerability scan (continues even if Talisman failed)
44+
echo "Running Snyk vulnerability scan..."
45+
snyk test --all-projects --fail-on=all > snyk_output.log 2>&1
46+
snyk_exit_code=$?
47+
48+
if [ $snyk_exit_code -eq 0 ]; then
49+
echo "Snyk scan passed: No vulnerabilities found."
50+
elif [ $snyk_exit_code -eq 1 ]; then
51+
echo "Snyk found vulnerabilities. See snyk_output.log for details."
52+
snyk_failed=true
53+
else
54+
echo "Snyk scan failed with error (exit code $snyk_exit_code). See snyk_output.log for details."
55+
snyk_failed=true
56+
fi
57+
58+
# Evaluate results after both scans
59+
if [ "$talisman_failed" = true ] || [ "$snyk_failed" = true ]; then
60+
echo "Commit aborted due to issues found in one or both scans."
61+
[ "$talisman_failed" = true ] && echo "- Talisman issues: Check talisman_output.log"
62+
[ "$snyk_failed" = true ] && echo "- Snyk issues: Check snyk_output.log"
63+
exit 1
64+
fi
65+
66+
# If both scans pass, allow the commit
67+
echo "All scans passed. Proceeding with commit."
68+
rm -f talisman_output.log snyk_output.log
69+
exit 0

.husky/pre-push

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
#!/usr/bin/env sh
2+
3+
echo "🚀 Running pre-push checks..."
4+
5+
# Activate virtual environment if it exists
6+
if [ -d "venv" ]; then
7+
echo "🔧 Activating virtual environment..."
8+
source venv/bin/activate
9+
fi
10+
11+
# Run tests to ensure code quality
12+
echo "🧪 Running tests..."
13+
if ! pytest --html=tests/report/test-report.html; then
14+
echo "❌ Tests failed. Please fix before pushing."
15+
exit 1
16+
fi
17+
18+
# Run coverage check
19+
echo "📊 Checking test coverage..."
20+
if ! pytest --cov=contentstack --cov-report=term-missing; then
21+
echo "❌ Coverage check failed. Please improve test coverage."
22+
exit 1
23+
fi
24+
25+
# Run security scan on dependencies (optional)
26+
if [ -n "$SNYK_TOKEN" ]; then
27+
echo "🔍 Running comprehensive Snyk scan..."
28+
if ! snyk test --severity-threshold=high; then
29+
echo "❌ High severity vulnerabilities found. Please fix before pushing."
30+
exit 1
31+
fi
32+
fi
33+
34+
echo "✅ All pre-push checks passed!"

requirements.txt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,4 +60,8 @@ cachetools~=5.4.0
6060
tomlkit~=0.13.2
6161
urllib3==2.5.0
6262
exceptiongroup~=1.2.2
63-
iniconfig~=2.0.0
63+
iniconfig~=2.0.0
64+
pytest-cov>=4.0.0
65+
pytest-html>=3.0.0
66+
black>=23.0.0
67+
flake8>=6.0.0

0 commit comments

Comments
 (0)