From 9acffe1e569f961380a68bbdb1d82fb2e96de4b4 Mon Sep 17 00:00:00 2001 From: ggman12 Date: Thu, 12 Feb 2026 15:31:53 -0500 Subject: [PATCH] handle multiple PRs with schema changes --- .github/workflows/update-community-prs.yaml | 100 ++++++++++++++++++++ src/contributions/regenerate_pr_schema.py | 68 +++++++++++++ 2 files changed, 168 insertions(+) create mode 100644 .github/workflows/update-community-prs.yaml create mode 100644 src/contributions/regenerate_pr_schema.py diff --git a/.github/workflows/update-community-prs.yaml b/.github/workflows/update-community-prs.yaml new file mode 100644 index 0000000..45ff59d --- /dev/null +++ b/.github/workflows/update-community-prs.yaml @@ -0,0 +1,100 @@ +name: Update Community PRs After Merge + +on: + push: + branches: [main] + paths: + - 'community/**' + - 'schemas/community_submission.*.schema.json' + +permissions: + contents: write + pull-requests: write + +jobs: + update-open-prs: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + token: ${{ secrets.GITHUB_TOKEN }} + + - name: Setup Python + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install dependencies + run: pip install jsonschema + + - name: Get current schema version + id: schema + run: | + # Find the latest schema version on main + latest=$(ls schemas/community_submission.v*.schema.json 2>/dev/null | sed 's/.*\.v\([0-9]*\)\.schema\.json/\1/' | sort -n | tail -1) + echo "latest_version=${latest:-1}" >> "$GITHUB_OUTPUT" + echo "Latest schema version: ${latest:-1}" + + - name: Find and update open community PRs + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + LATEST_SCHEMA_VERSION: ${{ steps.schema.outputs.latest_version }} + run: | + # Get list of open community PRs + prs=$(gh pr list --label community --state open --json number,headRefName --jq '.[] | "\(.number) \(.headRefName)"') + + if [ -z "$prs" ]; then + echo "No open community PRs found" + exit 0 + fi + + echo "$prs" | while read pr_number branch_name; do + echo "Processing PR #$pr_number (branch: $branch_name)" + + # Checkout PR branch + git fetch origin "$branch_name" + git checkout "$branch_name" + + # Check if this PR has a schema file that needs updating + pr_schema=$(ls schemas/community_submission.v*.schema.json 2>/dev/null | sed 's/.*\.v\([0-9]*\)\.schema\.json/\1/' | sort -n | tail -1) + + if [ "$pr_schema" -le "$LATEST_SCHEMA_VERSION" ] 2>/dev/null; then + echo " PR schema version ($pr_schema) <= main version ($LATEST_SCHEMA_VERSION)" + + # Merge main into PR branch + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + + if git merge origin/main -m "Merge main to update schema baseline"; then + # Regenerate schema for this PR's submission + python -m src.contributions.regenerate_pr_schema || true + + # If there are changes, commit and push + if [ -n "$(git status --porcelain schemas/)" ]; then + new_version=$((LATEST_SCHEMA_VERSION + 1)) + git add schemas/ + git commit -m "Update schema to v${new_version} (rebased on main)" + git push origin "$branch_name" + echo " Updated PR #$pr_number with new schema" + else + git push origin "$branch_name" + echo " Merged main into PR #$pr_number" + fi + else + echo " Merge conflict in PR #$pr_number, adding comment" + gh pr comment "$pr_number" --body "⚠️ **Merge Conflict** + +Another community submission was merged and this PR has conflicts. + +A maintainer may need to: +1. Close this PR +2. Remove the \`approved\` label from the original issue +3. Re-add the \`approved\` label to regenerate the PR" + git merge --abort + fi + fi + + git checkout main + done diff --git a/src/contributions/regenerate_pr_schema.py b/src/contributions/regenerate_pr_schema.py new file mode 100644 index 0000000..9d3936d --- /dev/null +++ b/src/contributions/regenerate_pr_schema.py @@ -0,0 +1,68 @@ +#!/usr/bin/env python3 +""" +Regenerate schema for a PR branch after main has been merged in. +This script looks at the submission files in this branch and generates +an updated schema version if new tags were introduced. + +Usage: python -m src.contributions.regenerate_pr_schema +""" + +import json +import sys +from pathlib import Path + +# Add parent to path for imports when running as script +sys.path.insert(0, str(Path(__file__).parent.parent.parent)) + +from src.contributions.read_community_data import read_all_submissions, build_tag_type_registry +from src.contributions.update_schema import ( + get_existing_tag_definitions, + check_for_new_tags, + generate_new_schema, +) +from src.contributions.schema import get_latest_schema_version, load_schema, SCHEMAS_DIR + + +def main(): + """Main entry point.""" + # Get current schema version and load it + current_version = get_latest_schema_version() + current_schema = load_schema() + + # Get existing tag definitions from schema + existing_tags = get_existing_tag_definitions(current_schema) + + # Read all submissions (including ones from this PR branch) + submissions = read_all_submissions() + + if not submissions: + print("No submissions found") + return + + # Build tag registry from all submissions + tag_registry = build_tag_type_registry(submissions) + + # Check for new tags not in the current schema + new_tags = check_for_new_tags(tag_registry, current_schema) + + if new_tags: + # Generate new schema version + new_version = current_version + 1 + print(f"Found new tags: {new_tags}") + print(f"Generating schema v{new_version}") + + # Generate new schema with updated tag definitions + new_schema = generate_new_schema(current_schema, tag_registry, new_version) + + # Write new schema version + new_schema_path = SCHEMAS_DIR / f"community_submission.v{new_version}.schema.json" + with open(new_schema_path, 'w') as f: + json.dump(new_schema, f, indent=2) + + print(f"Created {new_schema_path}") + else: + print("No new tags found, schema is up to date") + + +if __name__ == "__main__": + main()