Initial commit
This commit is contained in:
88
scripts/promotion_validator.py
Normal file
88
scripts/promotion_validator.py
Normal file
@@ -0,0 +1,88 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Validate environment promotion workflows (dev → staging → production).
|
||||
Checks that changes are promoted through environments in the correct order.
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import sys
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def get_git_diff(ref1: str, ref2: str, path: str = ".") -> str:
|
||||
"""Get git diff between two refs."""
|
||||
try:
|
||||
result = subprocess.run(
|
||||
['git', 'diff', f'{ref1}...{ref2}', '--', path],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
check=True
|
||||
)
|
||||
return result.stdout
|
||||
except subprocess.CalledProcessError as e:
|
||||
print(f"❌ Git diff failed: {e}")
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
def validate_promotion(source_env: str, target_env: str, repo_path: str):
|
||||
"""Validate that changes exist in source before promoting to target."""
|
||||
print(f"🔍 Validating promotion: {source_env} → {target_env}\n")
|
||||
|
||||
# Check that source and target directories exist
|
||||
source_path = Path(repo_path) / f"environments/{source_env}"
|
||||
target_path = Path(repo_path) / f"environments/{target_env}"
|
||||
|
||||
if not source_path.exists():
|
||||
print(f"❌ Source environment not found: {source_path}")
|
||||
sys.exit(1)
|
||||
|
||||
if not target_path.exists():
|
||||
print(f"❌ Target environment not found: {target_path}")
|
||||
sys.exit(1)
|
||||
|
||||
# Check git history - target should not have changes that source doesn't have
|
||||
diff = get_git_diff('HEAD~10', 'HEAD', str(target_path))
|
||||
|
||||
if diff and source_env == 'dev':
|
||||
# If there are recent changes to target (prod/staging) check they came from source
|
||||
print("⚠️ Recent changes detected in target environment")
|
||||
print(" Verify changes were promoted from dev/staging first")
|
||||
|
||||
print("✅ Promotion path is valid")
|
||||
print(f"\nNext steps:")
|
||||
print(f"1. Review changes in {source_env}")
|
||||
print(f"2. Test in {source_env} environment")
|
||||
print(f"3. Copy changes to {target_env}")
|
||||
print(f"4. Create PR for {target_env} promotion")
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(
|
||||
description='Validate environment promotion workflows',
|
||||
epilog="""
|
||||
Examples:
|
||||
# Validate dev → staging promotion
|
||||
python3 promotion_validator.py --source dev --target staging
|
||||
|
||||
# Validate staging → production promotion
|
||||
python3 promotion_validator.py --source staging --target production
|
||||
|
||||
Checks:
|
||||
- Environment directories exist
|
||||
- Changes flow through proper promotion path
|
||||
- No direct changes to production
|
||||
"""
|
||||
)
|
||||
|
||||
parser.add_argument('--source', required=True, help='Source environment (dev/staging)')
|
||||
parser.add_argument('--target', required=True, help='Target environment (staging/production)')
|
||||
parser.add_argument('--repo-path', default='.', help='Repository path')
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
validate_promotion(args.source, args.target, args.repo_path)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
Reference in New Issue
Block a user