From 78abd3524f22db2f3bd6cd4624f2182c4a520042 Mon Sep 17 00:00:00 2001 From: Matthew Buske Date: Fri, 6 Jun 2025 15:15:49 -0400 Subject: [PATCH 1/2] Configures Git for GitHub Actions Adds steps to configure Git user and safe directory settings for GitHub Actions workflows. Enhances compatibility and avoids potential permission issues during automated tasks. Relates to CI/CD improvements. --- .github/workflows/test.bridge.yml | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/.github/workflows/test.bridge.yml b/.github/workflows/test.bridge.yml index 9e56b07..9f75ad9 100644 --- a/.github/workflows/test.bridge.yml +++ b/.github/workflows/test.bridge.yml @@ -24,6 +24,12 @@ jobs: with: fetch-depth: 0 + - name: Configure Git + run: | + git config --global user.name "github-actions[bot]" + git config --global user.email "github-actions[bot]@users.noreply.github.com" + git config --global --add safe.directory /github/workspace + - name: Set up Python uses: actions/setup-python@v5 with: @@ -233,14 +239,16 @@ except Exception as e: - name: Checkout Repository uses: actions/checkout@v4 + - name: Configure Git + run: | + git config --global user.name "github-actions[bot]" + git config --global user.email "github-actions[bot]@users.noreply.github.com" + git config --global --add safe.directory /github/workspace + - name: Test Tag Operations Action run: | echo "=== Testing Tag Operations Action ===" - # Set up git for testing - git config user.name "Test User" - git config user.email "test@example.com" - # Test the generated tag-operations action if it exists if [ -d "actions/core/tag-operations" ]; then echo "Found generated tag-operations action" From 87adf19325c109611b54386d69d71d0e457c2b5c Mon Sep 17 00:00:00 2001 From: Matthew Buske Date: Fri, 6 Jun 2025 15:18:02 -0400 Subject: [PATCH 2/2] Refines YAML validation and test result commenting Reformats Python and JavaScript code for readability and consistency Improves test result comments with enhanced details on test execution Ensures consistent code indentation across the workflow script --- .github/workflows/test.bridge.yml | 262 +++++++++++++++--------------- 1 file changed, 131 insertions(+), 131 deletions(-) diff --git a/.github/workflows/test.bridge.yml b/.github/workflows/test.bridge.yml index 9f75ad9..60d0400 100644 --- a/.github/workflows/test.bridge.yml +++ b/.github/workflows/test.bridge.yml @@ -135,100 +135,100 @@ jobs: # Basic YAML validation using Python python -c " -import yaml -import sys -try: - with open('$action_yml', 'r') as f: - content = f.read() - - # Skip header comments for YAML parsing - yaml_content = '\n'.join(line for line in content.split('\n') if not line.strip().startswith('#')) - config = yaml.safe_load(yaml_content) - - # Check required GitHub Action fields - required_fields = ['name', 'runs'] - missing = [field for field in required_fields if field not in config] - - if missing: - print(f'❌ Missing required fields in $action_name: {missing}') - sys.exit(1) - - # Check runs configuration - if 'using' not in config['runs']: - print(f'❌ Missing runs.using in $action_name') - sys.exit(1) - - print(f'✅ $action_name is valid GitHub Action') - -except Exception as e: - print(f'❌ Error validating $action_name: {e}') - sys.exit(1) -" - fi - done - - - name: Upload Test Results - if: always() - uses: actions/upload-artifact@v4 - with: - name: bridge-test-results - path: | - .bridge/test-results.json - .bridge/validation-report.txt - retention-days: 30 - - - name: Comment Test Results - if: github.event_name == 'pull_request' - uses: actions/github-script@v7 - with: - script: | - const fs = require('fs'); - - let comment = '## 🔗 Bridge Test Results\n\n'; - - try { - // Read test results if available - if (fs.existsSync('.bridge/test-results.json')) { - const results = JSON.parse(fs.readFileSync('.bridge/test-results.json', 'utf8')); - const summary = results.summary; - - comment += `### Test Summary\n`; - comment += `- **Total Tests**: ${summary.total}\n`; - comment += `- **Passed**: ${summary.passed} ✅\n`; - comment += `- **Failed**: ${summary.failed} ${summary.failed > 0 ? '❌' : ''}\n`; - comment += `- **Skipped**: ${summary.skipped} ⏭️\n`; + import yaml + import sys + try: + with open('$action_yml', 'r') as f: + content = f.read() + + # Skip header comments for YAML parsing + yaml_content = '\n'.join(line for line in content.split('\n') if not line.strip().startswith('#')) + config = yaml.safe_load(yaml_content) + + # Check required GitHub Action fields + required_fields = ['name', 'runs'] + missing = [field for field in required_fields if field not in config] + + if missing: + print(f'❌ Missing required fields in $action_name: {missing}') + sys.exit(1) + + # Check runs configuration + if 'using' not in config['runs']: + print(f'❌ Missing runs.using in $action_name') + sys.exit(1) + + print(f'✅ $action_name is valid GitHub Action') + + except Exception as e: + print(f'❌ Error validating $action_name: {e}') + sys.exit(1) + " + fi + done - const successRate = summary.total > 0 ? (summary.passed / summary.total * 100).toFixed(1) : 0; - comment += `- **Success Rate**: ${successRate}%\n\n`; + - name: Upload Test Results + if: always() + uses: actions/upload-artifact@v4 + with: + name: bridge-test-results + path: | + .bridge/test-results.json + .bridge/validation-report.txt + retention-days: 30 - if (summary.failed > 0) { - comment += `### Failed Tests\n`; - const failedTests = results.tests.filter(t => t.status === 'failed'); - failedTests.forEach(test => { - comment += `- ❌ **${test.name}**: ${test.message}\n`; - }); - comment += '\n'; - } - } else { - comment += 'Test results file not found.\n\n'; - } - } catch (error) { - comment += `Error reading test results: ${error.message}\n\n`; - } - - comment += `### Architecture Status\n`; - comment += `- FCM Definitions: \`axioms/\`\n`; - comment += `- Generated Actions: \`actions/core/\`\n`; - comment += `- Bridge Infrastructure: \`.bridge/\`\n\n`; - comment += `For detailed results, check the workflow artifacts.`; - - // Post comment - github.rest.issues.createComment({ - issue_number: context.issue.number, - owner: context.repo.owner, - repo: context.repo.repo, - body: comment - }); + - name: Comment Test Results + if: github.event_name == 'pull_request' + uses: actions/github-script@v7 + with: + script: | + const fs = require('fs'); + + let comment = '## 🔗 Bridge Test Results\n\n'; + + try { + // Read test results if available + if (fs.existsSync('.bridge/test-results.json')) { + const results = JSON.parse(fs.readFileSync('.bridge/test-results.json', 'utf8')); + const summary = results.summary; + + comment += `### Test Summary\n`; + comment += `- **Total Tests**: ${summary.total}\n`; + comment += `- **Passed**: ${summary.passed} ✅\n`; + comment += `- **Failed**: ${summary.failed} ${summary.failed > 0 ? '❌' : ''}\n`; + comment += `- **Skipped**: ${summary.skipped} ⏭️\n`; + + const successRate = summary.total > 0 ? (summary.passed / summary.total * 100).toFixed(1) : 0; + comment += `- **Success Rate**: ${successRate}%\n\n`; + + if (summary.failed > 0) { + comment += `### Failed Tests\n`; + const failedTests = results.tests.filter(t => t.status === 'failed'); + failedTests.forEach(test => { + comment += `- ❌ **${test.name}**: ${test.message}\n`; + }); + comment += '\n'; + } + } else { + comment += 'Test results file not found.\n\n'; + } + } catch (error) { + comment += `Error reading test results: ${error.message}\n\n`; + } + + comment += `### Architecture Status\n`; + comment += `- FCM Definitions: \`axioms/\`\n`; + comment += `- Generated Actions: \`actions/core/\`\n`; + comment += `- Bridge Infrastructure: \`.bridge/\`\n\n`; + comment += `For detailed results, check the workflow artifacts.`; + + // Post comment + github.rest.issues.createComment({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + body: comment + }); action-tests: name: Test Generated Actions @@ -280,43 +280,43 @@ except Exception as e: # Use Python to parse and validate the action interface python -c " -import yaml -import sys + import yaml + import sys -try: - with open('$action_dir/action.yml', 'r') as f: - content = f.read() - - # Skip header comments - yaml_content = '\n'.join(line for line in content.split('\n') if not line.strip().startswith('#')) - config = yaml.safe_load(yaml_content) - - # Validate inputs - inputs = config.get('inputs', {}) - if not inputs: - print(f'⚠️ $action_name has no inputs') - else: - for input_name, input_config in inputs.items(): - if 'description' not in input_config: - print(f'❌ $action_name input {input_name} missing description') - sys.exit(1) - if 'required' not in input_config: - print(f'❌ $action_name input {input_name} missing required field') - sys.exit(1) - print(f'✅ $action_name has {len(inputs)} valid inputs') - - # Validate outputs - outputs = config.get('outputs', {}) - if outputs: - for output_name, output_config in outputs.items(): - if 'description' not in output_config: - print(f'❌ $action_name output {output_name} missing description') - sys.exit(1) - print(f'✅ $action_name has {len(outputs)} valid outputs') - -except Exception as e: - print(f'❌ Error validating $action_name interface: {e}') - sys.exit(1) -" - fi - done \ No newline at end of file + try: + with open('$action_dir/action.yml', 'r') as f: + content = f.read() + + # Skip header comments + yaml_content = '\n'.join(line for line in content.split('\n') if not line.strip().startswith('#')) + config = yaml.safe_load(yaml_content) + + # Validate inputs + inputs = config.get('inputs', {}) + if not inputs: + print(f'⚠️ $action_name has no inputs') + else: + for input_name, input_config in inputs.items(): + if 'description' not in input_config: + print(f'❌ $action_name input {input_name} missing description') + sys.exit(1) + if 'required' not in input_config: + print(f'❌ $action_name input {input_name} missing required field') + sys.exit(1) + print(f'✅ $action_name has {len(inputs)} valid inputs') + + # Validate outputs + outputs = config.get('outputs', {}) + if outputs: + for output_name, output_config in outputs.items(): + if 'description' not in output_config: + print(f'❌ $action_name output {output_name} missing description') + sys.exit(1) + print(f'✅ $action_name has {len(outputs)} valid outputs') + + except Exception as e: + print(f'❌ Error validating $action_name interface: {e}') + sys.exit(1) + " + fi + done \ No newline at end of file