-
Notifications
You must be signed in to change notification settings - Fork 1
feat: add template sync validation to prevent consumer repo sync failures #857
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
20 commits
Select commit
Hold shift + click to select a range
9598298
fix: Prevent task decomposer from splitting compound words on unspace…
stranske 2f4ab62
chore(autofix): formatting/lint
github-actions[bot] 00e5b75
fix: Strip code blocks before parsing tasks in issue_scope_parser
stranske a62c1cc
fix: preserve code blocks in PR status summary without adding checkboxes
stranske dfd66e8
fix: apply same slash fix to _is_multi_action_task in capability_chec…
stranske 96ef587
feat: add template sync validation to prevent consumer repo sync fail…
stranske 79a9c94
chore(autofix): formatting/lint
github-actions[bot] 53406d9
docs: add template sync guidance to SYNC_WORKFLOW and SETUP_CHECKLIST
stranske f05d1b6
fix: address Codex review - fail on missing templates, sync creates n…
stranske 8a5df02
fix: add health-72-template-sync to workflow inventory and tests
stranske fbfe3c5
Merge branch 'main' into fix/template-sync-guard
stranske a76f6f1
test: Add comprehensive coverage for validate_template_sync.py
stranske 16885b7
chore(autofix): formatting/lint
github-actions[bot] 364f1f0
sync: Create 13 missing template files (FIX: actually commit them thi…
stranske 761f41d
fix: Actually rename workflow file to health-72-template-sync.yml
stranske 04f11b4
fix: Update workflow display name to match filename
stranske 1a865ca
fix: Make test_validate_template_sync tests work properly
stranske de7d273
chore(autofix): formatting/lint
github-actions[bot] 7725d8b
fix: Update test expectation for missing template directory
stranske 77b9331
chore: retrigger CI checks
stranske File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Some comments aren't visible on the classic Files Changed page.
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,37 @@ | ||
| name: Health 72 Template Sync | ||
|
|
||
| on: | ||
| pull_request: | ||
| paths: | ||
| - '.github/scripts/**/*.js' | ||
| - 'templates/consumer-repo/.github/scripts/**/*.js' | ||
| push: | ||
| branches: [main] | ||
| paths: | ||
| - '.github/scripts/**/*.js' | ||
| - 'templates/consumer-repo/.github/scripts/**/*.js' | ||
|
|
||
| jobs: | ||
| validate: | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
|
|
||
| - name: Set up Python | ||
| uses: actions/setup-python@v5 | ||
| with: | ||
| python-version: '3.11' | ||
|
|
||
| - name: Validate template sync | ||
| run: | | ||
| if ! python scripts/validate_template_sync.py; then | ||
| echo "" | ||
| echo "❌ FAILED: Template files are out of sync!" | ||
| echo "" | ||
| echo "To fix this error:" | ||
| echo " 1. Run: ./scripts/sync_templates.sh" | ||
| echo " 2. Commit the changes to templates/consumer-repo/" | ||
| echo " 3. Push to your branch" | ||
| echo "" | ||
| exit 1 | ||
| fi |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,39 @@ | ||
| #!/bin/bash | ||
| # Sync source scripts to template directory | ||
| set -e | ||
|
|
||
| SOURCE_DIR=".github/scripts" | ||
| TEMPLATE_DIR="templates/consumer-repo/.github/scripts" | ||
|
|
||
| echo "🔄 Syncing scripts to template directory..." | ||
|
|
||
| # Get list of files to sync (exclude tests) | ||
| FILES=$(find "$SOURCE_DIR" -name "*.js" -type f \ | ||
| | grep -v "__tests__" \ | ||
| | grep -v ".test.js" \ | ||
| | sed "s|^$SOURCE_DIR/||") | ||
|
|
||
| synced=0 | ||
| for file in $FILES; do | ||
| source_file="$SOURCE_DIR/$file" | ||
| template_file="$TEMPLATE_DIR/$file" | ||
|
|
||
| # Create parent directory if it doesn't exist | ||
| mkdir -p "$(dirname "$template_file")" | ||
|
|
||
| if [ ! -f "$template_file" ]; then | ||
| echo " ✓ Creating $file (new file)" | ||
| cp "$source_file" "$template_file" | ||
| synced=$((synced + 1)) || true | ||
| elif ! cmp -s "$source_file" "$template_file"; then | ||
| echo " ✓ Syncing $file" | ||
| cp "$source_file" "$template_file" | ||
| synced=$((synced + 1)) || true | ||
| fi | ||
| done | ||
|
|
||
| if [ $synced -eq 0 ]; then | ||
| echo "✅ All files already in sync" | ||
| else | ||
| echo "✅ Synced $synced file(s)" | ||
| fi |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,73 @@ | ||
| #!/usr/bin/env python3 | ||
| """ | ||
| Validate that template files are in sync with source files. | ||
|
|
||
| This prevents the common mistake of updating .github/scripts/ without | ||
| updating templates/consumer-repo/.github/scripts/, which causes sync | ||
| PRs to consumer repos to not be triggered. | ||
| """ | ||
| import hashlib | ||
| import sys | ||
| from pathlib import Path | ||
|
|
||
|
|
||
| def hash_file(path: Path) -> str: | ||
| """Compute SHA256 hash of a file.""" | ||
| return hashlib.sha256(path.read_bytes()).hexdigest() | ||
|
|
||
|
|
||
| def main() -> int: | ||
| repo_root = Path(__file__).parent.parent | ||
| source_dir = repo_root / ".github" / "scripts" | ||
| template_dir = repo_root / "templates" / "consumer-repo" / ".github" / "scripts" | ||
|
|
||
| if not source_dir.exists(): | ||
| print(f"❌ Source directory not found: {source_dir}") | ||
| return 1 | ||
|
|
||
| if not template_dir.exists(): | ||
| print(f"❌ Template directory not found: {template_dir}") | ||
| return 1 | ||
|
|
||
| # Files that should be synced (exclude test files and some specific scripts) | ||
| exclude_patterns = ["__tests__", ".test.js", "deploy", "release"] | ||
|
|
||
| mismatches = [] | ||
| source_files = [ | ||
| f | ||
| for f in source_dir.rglob("*.js") | ||
| if not any(pattern in str(f) for pattern in exclude_patterns) | ||
| ] | ||
|
|
||
| for source_file in source_files: | ||
| relative_path = source_file.relative_to(source_dir) | ||
| template_file = template_dir / relative_path | ||
|
|
||
| if not template_file.exists(): | ||
| mismatches.append(relative_path) | ||
| continue | ||
stranske marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| source_hash = hash_file(source_file) | ||
| template_hash = hash_file(template_file) | ||
|
|
||
| if source_hash != template_hash: | ||
| mismatches.append(relative_path) | ||
|
|
||
| if mismatches: | ||
| print("❌ Template files out of sync with source files:\n") | ||
| for path in mismatches: | ||
| template_file = template_dir / path | ||
| if not template_file.exists(): | ||
| print(f" • {path} (MISSING - needs to be created)") | ||
| else: | ||
| print(f" • {path} (out of sync)") | ||
| print("\n💡 To fix: ./scripts/sync_templates.sh") | ||
| print(" Then: git add templates/consumer-repo/.github/scripts/") | ||
| return 1 | ||
|
|
||
| print("✅ All template files in sync") | ||
| return 0 | ||
|
|
||
|
|
||
| if __name__ == "__main__": | ||
| sys.exit(main()) | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.