diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml new file mode 100644 index 0000000..34fb776 --- /dev/null +++ b/.github/workflows/deploy.yml @@ -0,0 +1,52 @@ +name: Deploy Registry + +on: + schedule: + - cron: '0 0 * * *' # Every midnight + workflow_dispatch: # Manual trigger + push: + branches: + - main # Trigger on push to main (e.g. script updates) + +permissions: + contents: read + pages: write + id-token: write + +concurrency: + group: "pages" + cancel-in-progress: false + +jobs: + build: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: '8.2' + + - name: Generate Registry & Releases + run: php scripts/generate_registry.php + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + # Upload the 'public' folder as an artifact for Pages + - name: Upload artifact + uses: actions/upload-pages-artifact@v3 + with: + path: 'public' + + deploy: + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + runs-on: ubuntu-latest + needs: build + steps: + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v4 diff --git a/scripts/generate_registry.php b/scripts/generate_registry.php new file mode 100644 index 0000000..8ebb2c7 --- /dev/null +++ b/scripts/generate_registry.php @@ -0,0 +1,155 @@ + [ + 'method' => 'GET', + 'header' => [ + 'User-Agent: Mivo-Registry-Bot', + $token ? "Authorization: token $token" : '' + ] + ] + ]; + $context = stream_context_create($opts); + return file_get_contents($url, false, $context); +} + +echo "Starting Registry Generation...\n"; + +// --- PART 1: PLUGINS --- + +$reposUrl = "https://api.github.com/orgs/$orgName/repos?per_page=100"; +$reposJson = fetchUrl($reposUrl, $githubToken); + +if ($reposJson) { + $repos = json_decode($reposJson, true); + $plugins = []; + + foreach ($repos as $repo) { + if (strpos($repo['name'], 'plugin-') !== 0) continue; + + echo "Processing Plugin: " . $repo['name'] . "\n"; + + // Fetch Release Info + $releaseUrl = "https://api.github.com/repos/$orgName/{$repo['name']}/releases/latest"; + $releaseJson = fetchUrl($releaseUrl, $githubToken); + $release = $releaseJson ? json_decode($releaseJson, true) : null; + + // Fetch plugin.php + $ref = $release ? $release['tag_name'] : $repo['default_branch']; + $rawUrl = "https://raw.githubusercontent.com/$orgName/{$repo['name']}/{$ref}/plugin.php"; + $pluginContent = fetchUrl($rawUrl, $githubToken); + + if (!$pluginContent) { + echo " - Warning: plugin.php not found in $ref. Skipping.\n"; + continue; + } + + // Parse Metadata + preg_match_all('/^\s*\*\s*([a-zA-Z0-9 ]+):\s*(.+)$/m', $pluginContent, $matches, PREG_SET_ORDER); + $metadata = []; + foreach ($matches as $match) { + $metadata[strtolower(trim($match[1]))] = trim($match[2]); + } + + if (empty($metadata['plugin name'])) { + echo " - Warning: 'Plugin Name' header missing. Skipping.\n"; + continue; + } + + // Determine Download + $downloadUrl = $repo['html_url'] . '/archive/refs/heads/' . $repo['default_branch'] . '.zip'; + $version = '0.0.1'; + + if ($release && !empty($release['assets'])) { + $downloadUrl = $release['assets'][0]['browser_download_url']; + $version = $release['tag_name']; + echo " > Using Release: $version\n"; + } else { + echo " > Using Branch: {$repo['default_branch']}\n"; + } + + // Construct Plugin + $plugins[] = [ + 'id' => $repo['name'], + 'name' => $metadata['plugin name'], + 'description' => $metadata['description'] ?? $repo['description'] ?? '', + 'author' => $metadata['author'] ?? $repo['owner']['login'], + 'version' => $metadata['version'] ?? $version, + 'category' => $metadata['category'] ?? 'Uncategorized', + 'tags' => array_filter(array_map('trim', explode(',', $metadata['tags'] ?? ''))), + 'repo' => $repo['html_url'], + 'download' => $downloadUrl, + // Pointing to EXTERNAL GitHub Repo for readme, as we don't host docs here + 'readme' => $repo['html_url'], + 'updated_at' => $repo['updated_at'] + ]; + echo " + Added: " . $metadata['plugin name'] . "\n"; + } + + file_put_contents($pluginsFile, json_encode($plugins, JSON_UNESCAPED_SLASHES)); + echo "Saved " . count($plugins) . " plugins to plugins.json\n"; +} else { + echo "Error: Failed to fetch repositories.\n"; +} + +// --- PART 2: RELEASES --- +echo "\nGenerating Mivo Release Archive...\n"; +$mivoReleasesUrl = "https://api.github.com/repos/mivodev/mivo/releases?per_page=100"; +$mivoReleasesJson = fetchUrl($mivoReleasesUrl, $githubToken); + +if ($mivoReleasesJson) { + $releasesRaw = json_decode($mivoReleasesJson, true); + $archive = []; + + foreach ($releasesRaw as $release) { + if ($release['draft']) continue; + + $assetUrl = $release['zipball_url']; + $size = 0; + + foreach ($release['assets'] as $asset) { + if ($asset['content_type'] === 'application/zip' || substr($asset['name'], -4) === '.zip') { + $assetUrl = $asset['browser_download_url']; + $size = $asset['size']; + break; + } + } + + $archive[] = [ + 'version' => $release['tag_name'], + 'date' => date('Y-m-d', strtotime($release['published_at'])), + 'size' => $size, + 'download' => $assetUrl, + 'notes' => $release['html_url'], + 'prerelease' => $release['prerelease'] + ]; + } + + file_put_contents($releasesFile, json_encode($archive, JSON_UNESCAPED_SLASHES)); + echo "Saved " . count($archive) . " releases to releases.json\n"; +} else { + echo "Warning: Failed to fetch Mivo releases.\n"; +}