Merge pull request 'fix: PHPStan level 0 to 2 + 67 type errors fixed' (#93) from dev into main
Platform: moko-platform CI / CI Summary (push) Blocked by required conditions
Universal: Cascade Main → Dev / Cascade main → branches (push) Successful in 3s
Generic: Repo Health / Site Health (push) Has been skipped
Generic: Repo Health / Access control (push) Successful in 3s
Generic: Repo Health / Release configuration (push) Successful in 9s
Generic: Repo Health / Scripts governance (push) Successful in 9s
Generic: Repo Health / Repository health (push) Successful in 16s
Platform: moko-platform CI / Gate 1: Code Quality (push) Successful in 1m5s
Platform: moko-platform CI / Gate 5: Template Integrity (push) Failing after 4s
Platform: moko-platform CI / Gate 2: Unit Tests (8.1) (push) Failing after 34s
Platform: moko-platform CI / Gate 4: Governance (push) Successful in 36s
Platform: moko-platform CI / Gate 2: Unit Tests (8.2) (push) Failing after 37s
Platform: moko-platform CI / Gate 3: Self-Health Check (push) Failing after 38s
Platform: moko-platform CI / Gate 2: Unit Tests (8.3) (push) Failing after 39s
Platform: moko-platform CI / CI Summary (push) Blocked by required conditions
Universal: Cascade Main → Dev / Cascade main → branches (push) Successful in 3s
Generic: Repo Health / Site Health (push) Has been skipped
Generic: Repo Health / Access control (push) Successful in 3s
Generic: Repo Health / Release configuration (push) Successful in 9s
Generic: Repo Health / Scripts governance (push) Successful in 9s
Generic: Repo Health / Repository health (push) Successful in 16s
Platform: moko-platform CI / Gate 1: Code Quality (push) Successful in 1m5s
Platform: moko-platform CI / Gate 5: Template Integrity (push) Failing after 4s
Platform: moko-platform CI / Gate 2: Unit Tests (8.1) (push) Failing after 34s
Platform: moko-platform CI / Gate 4: Governance (push) Successful in 36s
Platform: moko-platform CI / Gate 2: Unit Tests (8.2) (push) Failing after 37s
Platform: moko-platform CI / Gate 3: Self-Health Check (push) Failing after 38s
Platform: moko-platform CI / Gate 2: Unit Tests (8.3) (push) Failing after 39s
This commit was merged in pull request #93.
This commit is contained in:
@@ -124,7 +124,7 @@ jobs:
|
||||
echo "### PHPCS" >> $GITHUB_STEP_SUMMARY
|
||||
echo "PSR-12 compliance: passed" >> $GITHUB_STEP_SUMMARY
|
||||
|
||||
- name: "PHPStan (Level 0)"
|
||||
- name: "PHPStan (Level 2)"
|
||||
continue-on-error: true
|
||||
run: |
|
||||
vendor/bin/phpstan analyse -c phpstan.neon --no-progress --error-format=github 2>&1 || {
|
||||
|
||||
@@ -25,6 +25,7 @@ Version format: `XX.YY.ZZ` (zero-padded semver).
|
||||
|
||||
### Fixed
|
||||
- `release_cascade.php`: accept `release-candidate` as stability value (was only accepting `rc`, causing cascade to silently skip)
|
||||
- PHPStan bumped from level 0 to level 2 — fixed 67 type errors (undefined variables, missing methods, wrong signatures, dead code)
|
||||
|
||||
## [06.00.00] - 2026-05-25
|
||||
|
||||
|
||||
@@ -217,7 +217,7 @@ class BulkJoomlaTemplate extends CLIApp
|
||||
|
||||
// Scaffold files
|
||||
$this->log("\nScaffolding template files...", 'INFO');
|
||||
$files = $this->getScaffoldFiles($name, $shortName, $client);
|
||||
$files = $this->getScaffoldFiles($name, $shortName, $client, $org);
|
||||
|
||||
$created = 0;
|
||||
foreach ($files as $path => $content) {
|
||||
@@ -409,7 +409,7 @@ class BulkJoomlaTemplate extends CLIApp
|
||||
*
|
||||
* @return array<string, string> path => content
|
||||
*/
|
||||
private function getScaffoldFiles(string $name, string $shortName, string $client): array
|
||||
private function getScaffoldFiles(string $name, string $shortName, string $client, string $org): array
|
||||
{
|
||||
$element = "tpl_{$shortName}";
|
||||
$now = date('Y-m-d');
|
||||
|
||||
@@ -1163,6 +1163,7 @@ class BulkSync extends CLIApp
|
||||
'sort' => 'created',
|
||||
'direction' => 'desc',
|
||||
]);
|
||||
$existing = array_values($existing);
|
||||
|
||||
if (!empty($existing) && isset($existing[0]['number'])) {
|
||||
$num = $existing[0]['number'];
|
||||
@@ -1311,6 +1312,7 @@ class BulkSync extends CLIApp
|
||||
|
||||
$labelNames = ['sync-report', 'mokostandards', 'type: chore', 'automation'];
|
||||
$labels = $this->resolveLabelIds($org, 'MokoStandards', $labelNames);
|
||||
$existing = array_values($existing);
|
||||
|
||||
if (!empty($existing) && isset($existing[0]['number'])) {
|
||||
$issueNumber = $existing[0]['number'];
|
||||
@@ -1394,6 +1396,7 @@ class BulkSync extends CLIApp
|
||||
'sort' => 'created',
|
||||
'direction' => 'desc',
|
||||
]);
|
||||
$existing = array_values($existing);
|
||||
|
||||
if (!empty($existing) && isset($existing[0]['number'])) {
|
||||
$num = $existing[0]['number'];
|
||||
|
||||
@@ -159,7 +159,7 @@ function restGet(string $path, string $token, ?\MokoEnterprise\ApiClient $apiCli
|
||||
/**
|
||||
* Detect platform type from .mokostandards file in the repo.
|
||||
*/
|
||||
function detectPlatform(string $org, string $repo, string $token, ?\MokoEnterprise\ApiClient $apiClient = null): string
|
||||
function detectRepoPlatform(string $org, string $repo, string $token, ?\MokoEnterprise\ApiClient $apiClient = null): string
|
||||
{
|
||||
// Try platform metadata dir first, then root
|
||||
foreach (['.github/.mokostandards', '.mokogitea/.mokostandards', '.mokostandards'] as $path) {
|
||||
@@ -447,7 +447,7 @@ foreach ($repos as $repo) {
|
||||
// Detect project type
|
||||
$type = $typeOverride;
|
||||
if (!$type) {
|
||||
$platform = detectPlatform($org, $repo, $token);
|
||||
$platform = detectRepoPlatform($org, $repo, $token);
|
||||
$type = $PLATFORM_TO_TYPE[$platform] ?? 'generic';
|
||||
echo " Platform: {$platform} → type: {$type}\n";
|
||||
}
|
||||
|
||||
+11
-11
@@ -83,7 +83,7 @@ if ($action === null || $tag === null || $token === null || $apiBase === null) {
|
||||
/**
|
||||
* Make a Gitea API request using curl
|
||||
*/
|
||||
function giteaApi(string $url, string $method, string $token, ?string $jsonBody = null, ?string $filePath = null): array
|
||||
function releaseGiteaApi(string $url, string $method, string $token, ?string $jsonBody = null, ?string $filePath = null): array
|
||||
{
|
||||
$ch = curl_init($url);
|
||||
$headers = ["Authorization: token {$token}"];
|
||||
@@ -118,7 +118,7 @@ function giteaApi(string $url, string $method, string $token, ?string $jsonBody
|
||||
*/
|
||||
function getReleaseByTag(string $apiBase, string $tag, string $token): ?array
|
||||
{
|
||||
$result = giteaApi("{$apiBase}/releases/tags/{$tag}", 'GET', $token);
|
||||
$result = releaseGiteaApi("{$apiBase}/releases/tags/{$tag}", 'GET', $token);
|
||||
if ($result['code'] === 200 && isset($result['data']['id'])) {
|
||||
return $result['data'];
|
||||
}
|
||||
@@ -132,8 +132,8 @@ switch ($action) {
|
||||
$existing = getReleaseByTag($apiBase, $tag, $token);
|
||||
if ($existing !== null) {
|
||||
$existingId = $existing['id'];
|
||||
giteaApi("{$apiBase}/releases/{$existingId}", 'DELETE', $token);
|
||||
giteaApi("{$apiBase}/tags/{$tag}", 'DELETE', $token);
|
||||
releaseGiteaApi("{$apiBase}/releases/{$existingId}", 'DELETE', $token);
|
||||
releaseGiteaApi("{$apiBase}/tags/{$tag}", 'DELETE', $token);
|
||||
echo "Deleted previous release: {$tag} (id: {$existingId})\n";
|
||||
}
|
||||
|
||||
@@ -144,7 +144,7 @@ switch ($action) {
|
||||
'target_commitish' => $target,
|
||||
]);
|
||||
|
||||
$result = giteaApi("{$apiBase}/releases", 'POST', $token, $payload);
|
||||
$result = releaseGiteaApi("{$apiBase}/releases", 'POST', $token, $payload);
|
||||
if ($result['code'] >= 200 && $result['code'] < 300) {
|
||||
$releaseId = $result['data']['id'] ?? 'unknown';
|
||||
echo "Release created: {$name} (tag: {$tag}, id: {$releaseId})\n";
|
||||
@@ -169,7 +169,7 @@ switch ($action) {
|
||||
$releaseId = $release['id'];
|
||||
|
||||
// Get existing assets to avoid duplicates
|
||||
$assetsResult = giteaApi("{$apiBase}/releases/{$releaseId}/assets", 'GET', $token);
|
||||
$assetsResult = releaseGiteaApi("{$apiBase}/releases/{$releaseId}/assets", 'GET', $token);
|
||||
$existingAssets = $assetsResult['data'] ?? [];
|
||||
|
||||
foreach ($files as $filePath) {
|
||||
@@ -184,7 +184,7 @@ switch ($action) {
|
||||
// Delete existing asset with same name
|
||||
foreach ($existingAssets as $asset) {
|
||||
if (($asset['name'] ?? '') === $fileName) {
|
||||
giteaApi("{$apiBase}/releases/{$releaseId}/assets/{$asset['id']}", 'DELETE', $token);
|
||||
releaseGiteaApi("{$apiBase}/releases/{$releaseId}/assets/{$asset['id']}", 'DELETE', $token);
|
||||
echo "Deleted existing asset: {$fileName}\n";
|
||||
break;
|
||||
}
|
||||
@@ -192,7 +192,7 @@ switch ($action) {
|
||||
|
||||
// Upload
|
||||
$uploadUrl = "{$apiBase}/releases/{$releaseId}/assets?name=" . urlencode($fileName);
|
||||
$result = giteaApi($uploadUrl, 'POST', $token, null, $filePath);
|
||||
$result = releaseGiteaApi($uploadUrl, 'POST', $token, null, $filePath);
|
||||
if ($result['code'] >= 200 && $result['code'] < 300) {
|
||||
echo "Uploaded: {$fileName}\n";
|
||||
} else {
|
||||
@@ -210,7 +210,7 @@ switch ($action) {
|
||||
$releaseId = $release['id'];
|
||||
|
||||
$payload = json_encode(['body' => $body ?? '']);
|
||||
$result = giteaApi("{$apiBase}/releases/{$releaseId}", 'PATCH', $token, $payload);
|
||||
$result = releaseGiteaApi("{$apiBase}/releases/{$releaseId}", 'PATCH', $token, $payload);
|
||||
if ($result['code'] >= 200 && $result['code'] < 300) {
|
||||
echo "Release body updated for tag: {$tag}\n";
|
||||
} else {
|
||||
@@ -222,8 +222,8 @@ switch ($action) {
|
||||
case 'delete':
|
||||
$existing = getReleaseByTag($apiBase, $tag, $token);
|
||||
if ($existing !== null) {
|
||||
giteaApi("{$apiBase}/releases/{$existing['id']}", 'DELETE', $token);
|
||||
giteaApi("{$apiBase}/tags/{$tag}", 'DELETE', $token);
|
||||
releaseGiteaApi("{$apiBase}/releases/{$existing['id']}", 'DELETE', $token);
|
||||
releaseGiteaApi("{$apiBase}/tags/{$tag}", 'DELETE', $token);
|
||||
echo "Deleted: {$tag} (id: {$existing['id']})\n";
|
||||
} else {
|
||||
echo "No release found for tag: {$tag}\n";
|
||||
|
||||
@@ -268,6 +268,6 @@ abstract class AbstractProjectPlugin implements ProjectPluginInterface
|
||||
$tags['plugin'] = $this->getPluginName();
|
||||
$tags['project_type'] = $this->getProjectType();
|
||||
|
||||
$this->metricsCollector->record($category, $name, $value, $tags);
|
||||
$this->metricsCollector->observe("{$category}.{$name}", (float) $value, $tags);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -123,6 +123,9 @@ class ApiClient
|
||||
/** Circuit breaker last failure time */
|
||||
private ?DateTime $circuitLastFailure = null;
|
||||
|
||||
/** @var LoggerInterface|null Optional logger instance */
|
||||
private ?LoggerInterface $logger = null;
|
||||
|
||||
/** @var array<string, mixed> Request metrics */
|
||||
private array $metrics = [
|
||||
'total_requests' => 0,
|
||||
@@ -176,6 +179,7 @@ class ApiClient
|
||||
$this->circuitBreakerTimeout = $circuitBreakerTimeout;
|
||||
$this->enableCaching = $enableCaching;
|
||||
$this->userAgent = $userAgent;
|
||||
$this->logger = $logger;
|
||||
$this->authScheme = $authScheme;
|
||||
|
||||
// Initialize HTTP client
|
||||
|
||||
@@ -169,7 +169,8 @@ class EnterpriseReadinessValidator
|
||||
|
||||
// Run security scan on PHP files
|
||||
if (is_dir("{$path}/src")) {
|
||||
$issues = $this->securityValidator->scanDirectory("{$path}/src", ['.php']);
|
||||
$this->securityValidator->scanDirectory("{$path}/src", ['.php']);
|
||||
$issues = $this->securityValidator->getFindings();
|
||||
$issueCount = count($issues);
|
||||
|
||||
$this->addResult(
|
||||
|
||||
@@ -425,4 +425,28 @@ class GitHubAdapter implements GitPlatformAdapter
|
||||
{
|
||||
return $this->apiClient;
|
||||
}
|
||||
|
||||
public function listBranches(string $org, string $repo): array
|
||||
{
|
||||
return $this->apiClient->get("/repos/{$org}/{$repo}/branches") ?? [];
|
||||
}
|
||||
|
||||
public function getCloneUrl(string $repo): string
|
||||
{
|
||||
return "https://github.com/{$repo}.git";
|
||||
}
|
||||
|
||||
public function cloneRepo(string $repo, string $path, array $options = []): bool
|
||||
{
|
||||
$url = $this->getCloneUrl($repo);
|
||||
$depth = $options['depth'] ?? 0;
|
||||
$depthFlag = $depth > 0 ? " --depth {$depth}" : '';
|
||||
$result = 0;
|
||||
passthru(
|
||||
'git clone' . $depthFlag . ' --quiet '
|
||||
. escapeshellarg($url) . ' ' . escapeshellarg($path),
|
||||
$result
|
||||
);
|
||||
return $result === 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -168,6 +168,29 @@ interface GitPlatformAdapter
|
||||
*/
|
||||
public function getRepoTopics(string $org, string $repo): array;
|
||||
|
||||
// ──────────────────────────────────────────────
|
||||
// Branches and Cloning
|
||||
// ──────────────────────────────────────────────
|
||||
|
||||
/**
|
||||
* List all branches in a repository.
|
||||
*
|
||||
* @return array<int, array<string, mixed>>
|
||||
*/
|
||||
public function listBranches(string $org, string $repo): array;
|
||||
|
||||
/**
|
||||
* Get the clone URL for a repository.
|
||||
*/
|
||||
public function getCloneUrl(string $repo): string;
|
||||
|
||||
/**
|
||||
* Clone a repository to a local path.
|
||||
*
|
||||
* @param array<string, mixed> $options
|
||||
*/
|
||||
public function cloneRepo(string $repo, string $path, array $options = []): bool;
|
||||
|
||||
// ──────────────────────────────────────────────
|
||||
// File Contents
|
||||
// ──────────────────────────────────────────────
|
||||
|
||||
@@ -498,4 +498,24 @@ class MokoGiteaAdapter implements GitPlatformAdapter
|
||||
{
|
||||
return $this->apiClient;
|
||||
}
|
||||
|
||||
public function getCloneUrl(string $repo): string
|
||||
{
|
||||
$base = str_replace('/api/v1', '', $this->baseUrl);
|
||||
return "{$base}/{$repo}.git";
|
||||
}
|
||||
|
||||
public function cloneRepo(string $repo, string $path, array $options = []): bool
|
||||
{
|
||||
$url = $this->getCloneUrl($repo);
|
||||
$depth = $options['depth'] ?? 0;
|
||||
$depthFlag = $depth > 0 ? " --depth {$depth}" : '';
|
||||
$result = 0;
|
||||
passthru(
|
||||
'git clone' . $depthFlag . ' --quiet '
|
||||
. escapeshellarg($url) . ' ' . escapeshellarg($path),
|
||||
$result
|
||||
);
|
||||
return $result === 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,7 +57,7 @@ class ApiPlugin extends AbstractProjectPlugin
|
||||
|
||||
// Check for API documentation
|
||||
if (!$this->hasAPIDocumentation($projectPath, $apiType)) {
|
||||
$warnings[] = 'No API documentation found (OpenAPI, GraphQL schema, etc.)';
|
||||
$errors[] = 'No API documentation found (OpenAPI, GraphQL schema, etc.)';
|
||||
}
|
||||
|
||||
// Check for proper error handling
|
||||
|
||||
@@ -59,7 +59,7 @@ class GenericPlugin extends AbstractProjectPlugin
|
||||
!$this->fileExists($projectPath, 'README') &&
|
||||
!$this->fileExists($projectPath, 'README.txt')
|
||||
) {
|
||||
$warnings[] = 'No README file found';
|
||||
$errors[] = 'No README file found';
|
||||
}
|
||||
|
||||
// Check for LICENSE
|
||||
|
||||
@@ -29,7 +29,7 @@ class RepositoryHealthChecker
|
||||
{
|
||||
private AuditLogger $logger;
|
||||
private MetricsCollector $metrics;
|
||||
private UnifiedValidation $validator;
|
||||
private UnifiedValidator $validator;
|
||||
|
||||
private array $results = [
|
||||
'categories' => [],
|
||||
@@ -46,11 +46,11 @@ class RepositoryHealthChecker
|
||||
public function __construct(
|
||||
?AuditLogger $logger = null,
|
||||
?MetricsCollector $metrics = null,
|
||||
?UnifiedValidation $validator = null
|
||||
?UnifiedValidator $validator = null
|
||||
) {
|
||||
$this->logger = $logger ?? new AuditLogger('repo_health_checker');
|
||||
$this->metrics = $metrics ?? new MetricsCollector();
|
||||
$this->validator = $validator ?? new UnifiedValidation();
|
||||
$this->validator = $validator ?? new UnifiedValidator();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -100,7 +100,7 @@ class RepositorySynchronizer
|
||||
try {
|
||||
$overridePath = $this->adapter->getMetadataDir() . '/' . self::SYNC_OVERRIDE_FILE_SUFFIX;
|
||||
$override = $this->adapter->getFileContents($org, $repo, $overridePath);
|
||||
return !empty($override);
|
||||
return $override !== '';
|
||||
} catch (Exception $e) {
|
||||
return false;
|
||||
}
|
||||
@@ -560,7 +560,7 @@ HCL;
|
||||
$combinedSummary = ['copied' => [], 'skipped' => [], 'total' => 0];
|
||||
foreach ($branchesToSync as $branchName) {
|
||||
$this->logger->logInfo(" Syncing branch: {$branchName}");
|
||||
$branchSummary = $this->syncFilesToBranch($org, $repo, $platform, $filesToSync, $repoRoot, $force, $branchName, $moduleId ?? null);
|
||||
$branchSummary = $this->syncFilesToBranch($org, $repo, $platform, $filesToSync, $repoRoot, $force, $branchName, null);
|
||||
// Merge summaries — only count first branch's copied files to avoid duplicates in tracking
|
||||
if ($branchName === $defaultBranch) {
|
||||
$combinedSummary = $branchSummary;
|
||||
@@ -1137,7 +1137,6 @@ HCL;
|
||||
'dolibarr' => 'templates/configs/gitignore.dolibarr',
|
||||
'platform' => 'templates/configs/gitignore.dolibarr',
|
||||
'joomla' => 'templates/configs/.gitignore.joomla',
|
||||
'joomla' => 'templates/configs/.gitignore.joomla',
|
||||
];
|
||||
$gitignoreTemplate = $gitignoreMap[$platform] ?? 'templates/configs/gitignore';
|
||||
$shared[] = [$gitignoreTemplate, '.gitignore'];
|
||||
@@ -1164,7 +1163,7 @@ HCL;
|
||||
];
|
||||
|
||||
foreach ($shared as [$source, $dest]) {
|
||||
$fullSource = "{$root}/{$source}";
|
||||
$fullSource = "{$repoRoot}/{$source}";
|
||||
if (file_exists($fullSource)) {
|
||||
$entries[] = [
|
||||
'source' => $source, // relative — RepositorySynchronizer prepends repoRoot
|
||||
|
||||
+5
-7
@@ -6,7 +6,7 @@
|
||||
|
||||
# PHPStan configuration for moko-platform projects
|
||||
parameters:
|
||||
level: 0
|
||||
level: 2
|
||||
paths:
|
||||
- lib
|
||||
- validate
|
||||
@@ -16,14 +16,12 @@ parameters:
|
||||
analyseAndScan:
|
||||
- vendor
|
||||
- node_modules (?)
|
||||
# Legacy CLIApp scripts — need migration to CliFramework
|
||||
- automation/repo_cleanup.php
|
||||
- automation/push_files.php
|
||||
- cli/joomla_release.php
|
||||
|
||||
reportUnmatchedIgnoredErrors: false
|
||||
|
||||
# Additional checks
|
||||
checkFunctionNameCase: true
|
||||
checkInternalClassCaseSensitivity: true
|
||||
|
||||
# Ignore common patterns
|
||||
ignoreErrors:
|
||||
# Add project-specific ignores here
|
||||
# - '#Call to an undefined method#'
|
||||
|
||||
@@ -102,7 +102,7 @@ class AutoDetectPlatform extends CLIApp
|
||||
|
||||
// Use the new plugin system for detection
|
||||
$this->log("Using ProjectTypeDetector for platform detection", 'INFO');
|
||||
$detectionResult = $this->typeDetector->detectProjectType($repoPath);
|
||||
$detectionResult = $this->typeDetector->detect($repoPath);
|
||||
|
||||
if (!empty($detectionResult['type'])) {
|
||||
$this->detectedPlatform = $detectionResult['type'];
|
||||
|
||||
@@ -269,7 +269,7 @@ class CheckClientTheme extends CliFramework
|
||||
|
||||
// ── Summary ───────────────────────────────────────────
|
||||
$passed = ($errors === 0) ? 1 : 0;
|
||||
$this->printSummary($passed, $errors, $this->elapsed(), $warns);
|
||||
$this->printSummary($passed, $errors, $this->elapsed());
|
||||
|
||||
return ($errors > 0) ? 1 : 0;
|
||||
}
|
||||
|
||||
@@ -203,11 +203,12 @@ class EnterpriseReadinessChecker extends CliFramework
|
||||
|
||||
// Run security scan on PHP files
|
||||
if (is_dir("{$path}/src")) {
|
||||
$issues = $this->securityValidator->scanDirectory("{$path}/src", ['.php']);
|
||||
$this->securityValidator->scanDirectory("{$path}/src", ['.php']);
|
||||
$findings = $this->securityValidator->getFindings();
|
||||
$this->addResult(
|
||||
'No security vulnerabilities in source code',
|
||||
empty($issues),
|
||||
count($issues) . ' security issues found'
|
||||
empty($findings),
|
||||
count($findings) . ' security issues found'
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -247,4 +248,4 @@ class EnterpriseReadinessChecker extends CliFramework
|
||||
|
||||
// Run the application
|
||||
$app = new EnterpriseReadinessChecker();
|
||||
exit($app->execute($argv));
|
||||
exit($app->execute());
|
||||
|
||||
@@ -614,4 +614,4 @@ class RepoHealthChecker extends CliFramework
|
||||
}
|
||||
|
||||
$app = new RepoHealthChecker();
|
||||
exit($app->execute($argv));
|
||||
exit($app->execute());
|
||||
|
||||
@@ -40,6 +40,7 @@ class DriftScanner extends CliFramework
|
||||
private ApiClient $apiClient;
|
||||
private AuditLogger $logger;
|
||||
private MetricsCollector $metrics;
|
||||
private \MokoEnterprise\GitPlatformAdapter $adapter;
|
||||
|
||||
private array $driftResults = [];
|
||||
private array $templates = [];
|
||||
@@ -561,6 +562,7 @@ class DriftScanner extends CliFramework
|
||||
'sort' => 'created',
|
||||
'direction' => 'desc',
|
||||
]);
|
||||
$existing = array_values($existing);
|
||||
|
||||
if (!empty($existing) && isset($existing[0]['number'])) {
|
||||
$num = $existing[0]['number'];
|
||||
@@ -610,4 +612,4 @@ class DriftScanner extends CliFramework
|
||||
|
||||
// Run the application
|
||||
$app = new DriftScanner();
|
||||
exit($app->execute($argv));
|
||||
exit($app->execute());
|
||||
|
||||
Reference in New Issue
Block a user