Create pr-assistant.yml #1
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
| name: PR Assistant | |
| on: | |
| pull_request: | |
| types: [opened, synchronize, reopened, closed] | |
| push: | |
| branches: [main, master] | |
| workflow_dispatch: | |
| permissions: | |
| contents: write | |
| pull-requests: write | |
| checks: write | |
| issues: write | |
| env: | |
| REQUIRED_WORKFLOW_SCHEMA_VERSION: "2.0.0" | |
| jobs: | |
| # ================================================================================= | |
| # JOB 1: PR Validation & Feedback | |
| # Validates example workflow definitions | |
| # ================================================================================= | |
| pr-validation: | |
| if: github.event_name == 'pull_request' && github.event.action != 'closed' | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout Code | |
| uses: actions/checkout@v6 | |
| - name: Set up Python | |
| uses: actions/setup-python@v6 | |
| with: | |
| python-version: '3.12' | |
| - name: Install Dependencies | |
| run: | | |
| pip install pyyaml | |
| # --- 1. Validate workflows.json (optional for examples) --- | |
| - name: 📋 Validate workflows.json | |
| run: | | |
| python << 'EOF' | |
| import json | |
| from pathlib import Path | |
| workflows_json = Path("workflows.json") | |
| if workflows_json.exists(): | |
| with open(workflows_json) as f: | |
| data = json.load(f) | |
| if "workflows" not in data or not isinstance(data["workflows"], list): | |
| print("❌ workflows.json must contain 'workflows' array") | |
| exit(1) | |
| print(f"✅ workflows.json valid ({len(data['workflows'])} examples)") | |
| else: | |
| print("ℹ️ workflows.json not found (optional for examples)") | |
| EOF | |
| # --- 2. Validate Example Workflow YAML Files --- | |
| - name: 📝 Validate Example Workflow YAML Files | |
| run: | | |
| python << 'EOF' | |
| import yaml | |
| import sys | |
| from pathlib import Path | |
| errors = [] | |
| validated = 0 | |
| print("Validating example workflow YAML files...") | |
| # Check all YAML files in examples directory | |
| for yaml_file in Path(".").rglob("*.yaml"): | |
| if ".github" in str(yaml_file): | |
| continue | |
| try: | |
| with open(yaml_file) as f: | |
| workflow_data = yaml.safe_load(f) | |
| if not workflow_data: | |
| continue | |
| # Basic validation (less strict for examples) | |
| if "id" not in workflow_data: | |
| errors.append(f"{yaml_file}: missing 'id' field") | |
| if "name" not in workflow_data: | |
| errors.append(f"{yaml_file}: missing 'name' field") | |
| # Trigger is recommended | |
| if "trigger" not in workflow_data: | |
| print(f"⚠️ {yaml_file}: missing 'trigger' (recommended)") | |
| if not any(e.startswith(str(yaml_file)) for e in errors): | |
| validated += 1 | |
| print(f"✅ {yaml_file} valid") | |
| except yaml.YAMLError as e: | |
| errors.append(f"{yaml_file}: Invalid YAML - {e}") | |
| except Exception as e: | |
| errors.append(f"{yaml_file}: {e}") | |
| if errors: | |
| print("\n❌ Errors found:") | |
| for e in errors: | |
| print(f" - {e}") | |
| sys.exit(1) | |
| else: | |
| print(f"\n✅ All {validated} example workflow(s) valid.") | |
| EOF | |
| # --- 3. Validate manifest.json (if exists) --- | |
| - name: 📄 Validate manifest.json | |
| run: | | |
| python << 'EOF' | |
| import json | |
| from pathlib import Path | |
| manifest_path = Path("manifest.json") | |
| if manifest_path.exists(): | |
| try: | |
| with open(manifest_path) as f: | |
| manifest = json.load(f) | |
| required_fields = ["schema_version", "domain", "name", "version"] | |
| for field in required_fields: | |
| if field not in manifest: | |
| print(f"⚠️ manifest.json missing field '{field}'") | |
| else: | |
| print(f"✅ manifest.json valid") | |
| except Exception as e: | |
| print(f"⚠️ Error reading manifest.json: {e}") | |
| else: | |
| print("ℹ️ manifest.json not found (optional)") | |
| EOF | |
| # --- 4. Feedback Comment --- | |
| - name: Feedback Comment | |
| if: always() | |
| uses: actions/github-script@v6 | |
| with: | |
| script: | | |
| const outcome = '${{ job.status }}'; | |
| if (outcome === 'failure') { | |
| github.rest.issues.createComment({ | |
| issue_number: context.issue.number, | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| body: "❌ **PR Validation Failed**\n\nPlease check:\n- Workflow YAML files are valid\n- Required fields (id, name) are present" | |
| }); | |
| } else if (outcome === 'success') { | |
| github.rest.issues.createComment({ | |
| issue_number: context.issue.number, | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| body: "✅ **PR Validation Passed**\n\nAll example workflow checks passed!" | |
| }); | |
| } | |
| # ================================================================================= | |
| # JOB 2: Thank Contributor | |
| # ================================================================================= | |
| thank-you: | |
| if: github.event_name == 'pull_request' && github.event.action == 'closed' && github.event.pull_request.merged == true | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/github-script@v6 | |
| with: | |
| script: | | |
| const author = context.payload.pull_request.user.login; | |
| const admins = ['FaserF', 'fabia', 'github-actions[bot]']; | |
| if (admins.includes(author)) return; | |
| github.rest.issues.createComment({ | |
| issue_number: context.issue.number, | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| body: `🎉 **Thank you @${author}!**\n\nYour contribution to the **faneX-ID Workflow Examples** is valuable! 🚀` | |
| }); |