Public Access
fa0b5b7865
- Add GA_TOKEN to token fallback chain across all 25 workflow templates
(secrets.GA_TOKEN || secrets.GH_TOKEN || github.token)
- Replace hardcoded MokoStandards clone URLs with platform-detecting
MOKO_CLONE_TOKEN/MOKO_CLONE_HOST env vars in 11 templates
- Replace actions/github-script@v7 with shell-based API calls in
repo_health (Joomla + Dolibarr) and validate-joomla-project
- Replace hardcoded ApiClient('api.github.com') with PlatformAdapterFactory
in health-check.yml and integration-tests.yml
- Add TODO markers for terraform github-script blocks (complex logic)
- Update publish-to-mokodolimods token references
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
377 lines
14 KiB
YAML
377 lines
14 KiB
YAML
# Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
|
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
# FILE INFORMATION
|
|
# DEFGROUP: Gitea.Workflow
|
|
# INGROUP: MokoStandards.IntegrationTests
|
|
# REPO: https://git.mokoconsulting.tech/mokoconsulting-tech/MokoStandards-API
|
|
# PATH: /.github/workflows/integration-tests.yml
|
|
# VERSION: 04.06.00
|
|
# BRIEF: Integration tests for all enterprise libraries with performance benchmarks
|
|
# NOTE: Tests all 13 PHP enterprise libraries and measures performance
|
|
|
|
name: Integration Tests
|
|
|
|
on:
|
|
schedule:
|
|
# Run daily at 04:00 UTC
|
|
- cron: '0 4 * * *'
|
|
pull_request:
|
|
branches:
|
|
- main
|
|
paths:
|
|
- 'api/lib/Enterprise/**'
|
|
- 'src/**/*.php'
|
|
workflow_dispatch:
|
|
inputs:
|
|
library_filter:
|
|
description: 'Filter specific library to test'
|
|
required: false
|
|
type: string
|
|
default: ''
|
|
run_benchmarks:
|
|
description: 'Run performance benchmarks'
|
|
required: false
|
|
type: boolean
|
|
default: true
|
|
|
|
permissions:
|
|
contents: read
|
|
|
|
jobs:
|
|
integration-tests:
|
|
name: Integration Tests
|
|
runs-on: ubuntu-latest
|
|
|
|
steps:
|
|
- name: Checkout Repository
|
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
|
|
|
- name: Set up PHP
|
|
uses: shivammathur/setup-php@accd6127cb78bee3e8082180cb391013d204ef9f # v2.37.0
|
|
with:
|
|
php-version: '8.1'
|
|
extensions: mbstring, curl, json
|
|
tools: composer
|
|
|
|
- name: Install Composer Dependencies
|
|
run: composer install --no-dev --optimize-autoloader
|
|
|
|
- name: Create Test Directories
|
|
run: |
|
|
mkdir -p logs/tests
|
|
mkdir -p logs/benchmarks
|
|
mkdir -p logs/reports
|
|
|
|
- name: Test Enterprise Libraries
|
|
id: test
|
|
run: |
|
|
echo "## 🧪 Enterprise Library Integration Tests" >> $GITHUB_STEP_SUMMARY
|
|
echo "" >> $GITHUB_STEP_SUMMARY
|
|
|
|
php << 'EOF'
|
|
<?php
|
|
require_once __DIR__ . '/vendor/autoload.php';
|
|
|
|
use MokoStandards\Enterprise\ApiClient;
|
|
use MokoStandards\Enterprise\AuditLogger;
|
|
use MokoStandards\Enterprise\CliFramework;
|
|
use MokoStandards\Enterprise\Config;
|
|
use MokoStandards\Enterprise\EnterpriseReadinessValidator;
|
|
use MokoStandards\Enterprise\RecoveryManager;
|
|
use MokoStandards\Enterprise\InputValidator;
|
|
use MokoStandards\Enterprise\MetricsCollector;
|
|
use MokoStandards\Enterprise\RepositoryHealthChecker;
|
|
use MokoStandards\Enterprise\RepositorySynchronizer;
|
|
use MokoStandards\Enterprise\SecurityValidator;
|
|
use MokoStandards\Enterprise\TransactionManager;
|
|
use MokoStandards\Enterprise\UnifiedValidation;
|
|
|
|
$testResults = [];
|
|
$failedTests = [];
|
|
|
|
// List of enterprise libraries to test
|
|
$libraries = [
|
|
'ApiClient' => ApiClient::class,
|
|
'AuditLogger' => AuditLogger::class,
|
|
'CliFramework' => CliFramework::class,
|
|
'Config' => Config::class,
|
|
'EnterpriseReadinessValidator' => EnterpriseReadinessValidator::class,
|
|
'RecoveryManager' => RecoveryManager::class,
|
|
'InputValidator' => InputValidator::class,
|
|
'MetricsCollector' => MetricsCollector::class,
|
|
'RepositoryHealthChecker' => RepositoryHealthChecker::class,
|
|
'RepositorySynchronizer' => RepositorySynchronizer::class,
|
|
'SecurityValidator' => SecurityValidator::class,
|
|
'TransactionManager' => TransactionManager::class,
|
|
'UnifiedValidation' => UnifiedValidation::class
|
|
];
|
|
|
|
$libraryFilter = '${{ github.event.inputs.library_filter }}';
|
|
if (!empty($libraryFilter)) {
|
|
$libraries = array_filter($libraries, function($name) use ($libraryFilter) {
|
|
return stripos($name, $libraryFilter) !== false;
|
|
}, ARRAY_FILTER_USE_KEY);
|
|
}
|
|
|
|
echo "Testing " . count($libraries) . " enterprise libraries...\n\n";
|
|
|
|
foreach ($libraries as $libName => $libClass) {
|
|
try {
|
|
$startTime = microtime(true);
|
|
|
|
// Library-specific tests
|
|
$testPassed = true;
|
|
$testDetails = ['version' => '04.00.04'];
|
|
|
|
switch ($libName) {
|
|
case 'ApiClient':
|
|
$cfg = \MokoEnterprise\Config::load();
|
|
$adp = \MokoEnterprise\PlatformAdapterFactory::create($cfg);
|
|
$client = $adp->getApiClient();
|
|
$testDetails['circuit_state'] = $client->getCircuitState();
|
|
break;
|
|
|
|
case 'AuditLogger':
|
|
$logger = new AuditLogger('test');
|
|
$testDetails['service'] = 'test';
|
|
break;
|
|
|
|
case 'MetricsCollector':
|
|
$metrics = new MetricsCollector('test');
|
|
$metrics->increment('test_metric');
|
|
$testDetails['test_metric'] = 1;
|
|
break;
|
|
|
|
case 'SecurityValidator':
|
|
$validator = new SecurityValidator();
|
|
$testDetails['version'] = $validator->getVersion();
|
|
break;
|
|
|
|
case 'Config':
|
|
$config = Config::load('test');
|
|
$testDetails['config_loaded'] = true;
|
|
$testDetails['environment'] = $config->get('environment');
|
|
break;
|
|
|
|
case 'RecoveryManager':
|
|
$recovery = new RecoveryManager();
|
|
$testDetails['initialized'] = true;
|
|
break;
|
|
|
|
default:
|
|
// Basic instantiation test for other libraries
|
|
if (class_exists($libClass)) {
|
|
$testDetails['class_exists'] = true;
|
|
}
|
|
break;
|
|
}
|
|
|
|
$elapsed = microtime(true) - $startTime;
|
|
$testDetails['load_time_ms'] = round($elapsed * 1000, 2);
|
|
|
|
$testResults[$libName] = [
|
|
'status' => 'passed',
|
|
'details' => $testDetails
|
|
];
|
|
echo "✅ {$libName}: PASSED ({$testDetails['load_time_ms']}ms)\n";
|
|
|
|
} catch (Exception $e) {
|
|
$testResults[$libName] = [
|
|
'status' => 'failed',
|
|
'error' => $e->getMessage()
|
|
];
|
|
$failedTests[] = $libName;
|
|
echo "❌ {$libName}: FAILED - {$e->getMessage()}\n";
|
|
}
|
|
}
|
|
|
|
// Save test results
|
|
file_put_contents('logs/tests/integration-results.json', json_encode($testResults, JSON_PRETTY_PRINT));
|
|
|
|
// Summary
|
|
$passed = count(array_filter($testResults, fn($r) => $r['status'] === 'passed'));
|
|
$total = count($testResults);
|
|
|
|
$summary = [
|
|
'total' => $total,
|
|
'passed' => $passed,
|
|
'failed' => count($failedTests),
|
|
'failed_libs' => $failedTests
|
|
];
|
|
file_put_contents('/tmp/test_summary.json', json_encode($summary));
|
|
|
|
echo "\n" . str_repeat('=', 50) . "\n";
|
|
echo "Total: {$total} | Passed: {$passed} | Failed: " . count($failedTests) . "\n";
|
|
echo str_repeat('=', 50) . "\n";
|
|
|
|
if (count($failedTests) > 0) {
|
|
exit(1);
|
|
}
|
|
EOF
|
|
|
|
# Read summary and output
|
|
if [ -f "/tmp/test_summary.json" ]; then
|
|
SUMMARY=$(cat /tmp/test_summary.json)
|
|
TOTAL=$(echo $SUMMARY | php -r 'echo json_decode(file_get_contents("php://stdin"), true)["total"];')
|
|
PASSED=$(echo $SUMMARY | php -r 'echo json_decode(file_get_contents("php://stdin"), true)["passed"];')
|
|
FAILED=$(echo $SUMMARY | php -r 'echo json_decode(file_get_contents("php://stdin"), true)["failed"];')
|
|
|
|
echo "total_tests=$TOTAL" >> $GITHUB_OUTPUT
|
|
echo "passed_tests=$PASSED" >> $GITHUB_OUTPUT
|
|
echo "failed_tests=$FAILED" >> $GITHUB_OUTPUT
|
|
|
|
echo "### Test Results" >> $GITHUB_STEP_SUMMARY
|
|
echo "- Total libraries: **${TOTAL}**" >> $GITHUB_STEP_SUMMARY
|
|
echo "- Passed: **${PASSED}** ✅" >> $GITHUB_STEP_SUMMARY
|
|
echo "- Failed: **${FAILED}** ❌" >> $GITHUB_STEP_SUMMARY
|
|
fi
|
|
|
|
- name: Performance Benchmarks
|
|
if: github.event.inputs.run_benchmarks != 'false'
|
|
run: |
|
|
echo "" >> $GITHUB_STEP_SUMMARY
|
|
echo "## ⚡ Performance Benchmarks" >> $GITHUB_STEP_SUMMARY
|
|
echo "" >> $GITHUB_STEP_SUMMARY
|
|
|
|
php << 'EOF'
|
|
<?php
|
|
require_once __DIR__ . '/vendor/autoload.php';
|
|
|
|
use MokoStandards\Enterprise\ApiClient;
|
|
use MokoStandards\Enterprise\AuditLogger;
|
|
use MokoStandards\Enterprise\MetricsCollector;
|
|
use MokoStandards\Enterprise\SecurityValidator;
|
|
|
|
$benchmarks = [];
|
|
|
|
try {
|
|
// Benchmark 1: API Client circuit breaker and metrics
|
|
$cfg = \MokoEnterprise\Config::load();
|
|
$adp = \MokoEnterprise\PlatformAdapterFactory::create($cfg);
|
|
$client = $adp->getApiClient();
|
|
$start = microtime(true);
|
|
for ($i = 0; $i < 100; $i++) {
|
|
// Get metrics to test circuit breaker monitoring
|
|
$metrics = $client->getMetrics();
|
|
}
|
|
$elapsed = microtime(true) - $start;
|
|
$benchmarks['api_client_metrics'] = [
|
|
'iterations' => 100,
|
|
'total_time_ms' => round($elapsed * 1000, 2),
|
|
'avg_time_ms' => round($elapsed * 1000 / 100, 4)
|
|
];
|
|
echo "✅ API Client metrics: {$benchmarks['api_client_metrics']['avg_time_ms']}ms/op\n";
|
|
|
|
// Benchmark 2: Audit logging
|
|
$logger = new AuditLogger('benchmark');
|
|
$start = microtime(true);
|
|
for ($i = 0; $i < 100; $i++) {
|
|
$logger->logEvent('test_event', ['iteration' => $i]);
|
|
}
|
|
$elapsed = microtime(true) - $start;
|
|
$benchmarks['audit_logging'] = [
|
|
'iterations' => 100,
|
|
'total_time_ms' => round($elapsed * 1000, 2),
|
|
'avg_time_ms' => round($elapsed * 1000 / 100, 4)
|
|
];
|
|
echo "✅ Audit logging: {$benchmarks['audit_logging']['avg_time_ms']}ms/op\n";
|
|
|
|
// Benchmark 3: Metrics collection
|
|
$metrics = new MetricsCollector('benchmark');
|
|
$start = microtime(true);
|
|
for ($i = 0; $i < 1000; $i++) {
|
|
$metrics->increment('test_counter');
|
|
$metrics->setGauge('test_gauge', $i);
|
|
}
|
|
$elapsed = microtime(true) - $start;
|
|
$benchmarks['metrics_collection'] = [
|
|
'iterations' => 1000,
|
|
'total_time_ms' => round($elapsed * 1000, 2),
|
|
'avg_time_ms' => round($elapsed * 1000 / 1000, 4)
|
|
];
|
|
echo "✅ Metrics collection: {$benchmarks['metrics_collection']['avg_time_ms']}ms/op\n";
|
|
|
|
// Benchmark 4: Security scanning
|
|
$validator = new SecurityValidator();
|
|
$testContent = str_repeat("password = 'test123'\napi_key = 'secret'\n", 10);
|
|
$start = microtime(true);
|
|
for ($i = 0; $i < 10; $i++) {
|
|
$validator->scanContent($testContent, 'test.php');
|
|
}
|
|
$elapsed = microtime(true) - $start;
|
|
$benchmarks['security_scanning'] = [
|
|
'iterations' => 10,
|
|
'total_time_ms' => round($elapsed * 1000, 2),
|
|
'avg_time_ms' => round($elapsed * 1000 / 10, 4)
|
|
];
|
|
echo "✅ Security scanning: {$benchmarks['security_scanning']['avg_time_ms']}ms/op\n";
|
|
|
|
// Save benchmarks
|
|
file_put_contents('logs/benchmarks/performance.json', json_encode($benchmarks, JSON_PRETTY_PRINT));
|
|
|
|
echo "\n✅ All benchmarks completed\n";
|
|
|
|
} catch (Exception $e) {
|
|
echo "⚠️ Benchmark failed: {$e->getMessage()}\n";
|
|
}
|
|
EOF
|
|
|
|
if [ -f "logs/benchmarks/performance.json" ]; then
|
|
echo "✅ Performance benchmarks completed" >> $GITHUB_STEP_SUMMARY
|
|
echo "" >> $GITHUB_STEP_SUMMARY
|
|
echo "See artifacts for detailed results" >> $GITHUB_STEP_SUMMARY
|
|
fi
|
|
|
|
- name: Generate Integration Report
|
|
if: always()
|
|
run: |
|
|
php << 'EOF'
|
|
<?php
|
|
require_once __DIR__ . '/vendor/autoload.php';
|
|
|
|
try {
|
|
$report = [
|
|
'test_date' => date('c'),
|
|
'repository' => 'MokoStandards',
|
|
'trigger' => '${{ github.event_name }}'
|
|
];
|
|
|
|
// Load test results
|
|
$testFile = 'logs/tests/integration-results.json';
|
|
if (file_exists($testFile)) {
|
|
$report['tests'] = json_decode(file_get_contents($testFile), true);
|
|
}
|
|
|
|
// Load benchmarks
|
|
$benchFile = 'logs/benchmarks/performance.json';
|
|
if (file_exists($benchFile)) {
|
|
$report['benchmarks'] = json_decode(file_get_contents($benchFile), true);
|
|
}
|
|
|
|
// Save report
|
|
file_put_contents('logs/reports/integration-report.json', json_encode($report, JSON_PRETTY_PRINT));
|
|
|
|
echo "✅ Integration report generated\n";
|
|
|
|
} catch (Exception $e) {
|
|
echo "⚠️ Report generation failed: {$e->getMessage()}\n";
|
|
}
|
|
EOF
|
|
|
|
- name: Upload Test Results
|
|
if: always()
|
|
uses: actions/upload-artifact@v6.0.0
|
|
with:
|
|
name: integration-test-results-${{ github.run_number }}
|
|
path: |
|
|
logs/tests/
|
|
logs/benchmarks/
|
|
logs/reports/integration-report.json
|
|
retention-days: 30
|
|
|
|
- name: Notify on Failure
|
|
if: failure()
|
|
run: |
|
|
echo "❌ Integration tests failed" >> $GITHUB_STEP_SUMMARY
|
|
echo "One or more library integrations are broken" >> $GITHUB_STEP_SUMMARY
|