From d8795c8a940ae93dabcc142368305316963526d8 Mon Sep 17 00:00:00 2001 From: ReenigneArcher <42013603+ReenigneArcher@users.noreply.github.com> Date: Tue, 23 Sep 2025 19:10:36 -0400 Subject: [PATCH] fix: make gh-pages static --- .github/scripts/sync-assets.js | 19 --- .github/workflows/sync-release-assets.yml | 44 ++++++- gh-pages-template/app.js | 151 +++++++++++++++++++--- 3 files changed, 172 insertions(+), 42 deletions(-) diff --git a/.github/scripts/sync-assets.js b/.github/scripts/sync-assets.js index d269d712..8a4fd1a9 100644 --- a/.github/scripts/sync-assets.js +++ b/.github/scripts/sync-assets.js @@ -148,22 +148,6 @@ async function processAsset(releaseDir, asset) { } } -/** - * Generate repository data JSON for the web interface - */ -function generateRepositoryDataJson(repositoryData, totalAssets) { - const dataJson = { - repositories: repositoryData, - lastUpdated: new Date().toISOString(), - totalRepositories: repositoryData.length, - totalReleases: repositoryData.reduce((sum, repo) => sum + repo.releases.length, 0), - totalAssets: totalAssets - }; - - writeFile('repository-data.json', JSON.stringify(dataJson, null, 2)); - console.log('Generated repository-data.json'); -} - /** * Main function to sync all release assets */ @@ -218,9 +202,6 @@ async function syncReleaseAssets(github, context, isPullRequest = false, maxNewA newAssetsDownloaded = result.newAssetsDownloaded; } - // Generate repository data JSON for the index.html - generateRepositoryDataJson(repositoryData, totalAssets); - if (isPullRequest) { console.log(`PR mode: Processed ${repositoryData.length} repositories with ${totalProcessedReleases} releases containing assets`); } else { diff --git a/.github/workflows/sync-release-assets.yml b/.github/workflows/sync-release-assets.yml index fc79490a..2c1ca903 100644 --- a/.github/workflows/sync-release-assets.yml +++ b/.github/workflows/sync-release-assets.yml @@ -12,10 +12,15 @@ env: on: workflow_dispatch: pull_request: + branches: + - master types: - opened - reopened - synchronize + push: + branches: + - master schedule: - cron: '0 * * * *' @@ -40,9 +45,6 @@ jobs: git rm -rf . 2>/dev/null || true fi - - name: Copy gh-pages template files to dist directory - run: cp -r gh-pages-template/* dist/ - - name: Get organization repositories and download assets uses: actions/github-script@v8 with: @@ -72,3 +74,39 @@ jobs: directory: dist github_token: ${{ secrets.GH_BOT_TOKEN }} message: 'Update release assets - ${{ github.run_id }}' + + deploy-website: + needs: sync-assets + runs-on: ubuntu-latest + if: github.event_name == 'push' && github.ref == 'refs/heads/master' + steps: + - name: Checkout repository + uses: actions/checkout@v5 + with: + token: ${{ secrets.GH_BOT_TOKEN }} + + - name: Create or checkout gh-pages branch into gh-pages directory + run: | + if git rev-parse --verify origin/gh-pages >/dev/null 2>&1; then + echo "gh-pages branch exists, checking it out" + git worktree add gh-pages origin/gh-pages + else + echo "gh-pages branch doesn't exist, creating new one" + git worktree add --orphan gh-pages + cd gh-pages + git rm -rf . 2>/dev/null || true + fi + + - name: Copy website files to gh-pages directory + run: | + cp -r gh-pages-template/* gh-pages/ + + - name: Commit and push changes + uses: actions-js/push@v1.5 + with: + author_email: ${{ secrets.GH_BOT_EMAIL }} + author_name: ${{ secrets.GH_BOT_NAME }} + branch: gh-pages + directory: gh-pages + github_token: ${{ secrets.GH_BOT_TOKEN }} + message: 'Update from ${{ github.sha }}' diff --git a/gh-pages-template/app.js b/gh-pages-template/app.js index 1c5d0da7..f23e36dc 100644 --- a/gh-pages-template/app.js +++ b/gh-pages-template/app.js @@ -1,43 +1,152 @@ /** * Repository Data Manager - * Handles loading and managing repository data from the JSON file + * Handles loading and managing repository data from GitHub API */ class RepositoryDataManager { constructor() { this.repositoryData = []; + this.orgName = 'LizardByte'; // Organization name + this.distBranch = 'dist'; + this.apiBase = 'https://api.github.com'; + this.rawBase = 'https://raw.githubusercontent.com'; } /** - * Load repository data from the JSON file or fallback to directory scanning + * Load repository data by scanning the dist branch via GitHub API */ async loadRepositoryData() { try { - // Try to load from the generated JSON file - const response = await fetch('./repository-data.json'); - if (response.ok) { - const data = await response.json(); - this.repositoryData = data.repositories || []; - return data; - } else { - // Fallback: scan the directory structure - await this.scanDirectoryStructure(); + console.log('Loading repository data from GitHub API...'); + + // Get the contents of the dist branch + const response = await fetch(`${this.apiBase}/repos/${this.orgName}/packages/contents?ref=${this.distBranch}`); + + if (!response.ok) { + throw new Error(`GitHub API error: ${response.status}`); + } + + const contents = await response.json(); + + // Filter for directories (repositories) + const repoDirs = contents.filter(item => item.type === 'dir'); + + console.log(`Found ${repoDirs.length} repository directories`); + + this.repositoryData = []; + + // Process each repository directory + for (const repoDir of repoDirs) { + const repoData = await this.processRepository(repoDir.name); + if (repoData && repoData.releases.length > 0) { + this.repositoryData.push(repoData); + } + } + + console.log(`Loaded data for ${this.repositoryData.length} repositories with releases`); + + return { + repositories: this.repositoryData, + lastUpdated: new Date().toISOString(), + totalRepositories: this.repositoryData.length, + totalReleases: this.repositoryData.reduce((sum, repo) => sum + repo.releases.length, 0), + totalAssets: this.repositoryData.reduce((sum, repo) => + sum + repo.releases.reduce((releaseSum, release) => releaseSum + release.assetCount, 0), 0) + }; + + } catch (error) { + console.error('Error loading repository data:', error); + // Fallback to empty data + this.repositoryData = []; + return null; + } + } + + /** + * Process a single repository directory to get release information + */ + async processRepository(repoName) { + try { + console.log(`Processing repository: ${repoName}`); + + // Get repository directory contents + const response = await fetch(`${this.apiBase}/repos/${this.orgName}/packages/contents/${repoName}?ref=${this.distBranch}`); + + if (!response.ok) { + console.warn(`Could not fetch contents for ${repoName}: ${response.status}`); + return null; + } + + const contents = await response.json(); + + // Filter for directories (releases) + const releaseDirs = contents.filter(item => item.type === 'dir'); + + if (releaseDirs.length === 0) { + console.log(`No release directories found for ${repoName}`); return null; } + + const repoData = { + name: repoName, + releases: [] + }; + + // Process each release directory + for (const releaseDir of releaseDirs) { + const releaseData = await this.processRelease(repoName, releaseDir.name); + if (releaseData) { + repoData.releases.push(releaseData); + } + } + + // Sort releases by tag name (newest first, assuming semantic versioning) + repoData.releases.sort((a, b) => b.tag.localeCompare(a.tag, undefined, { numeric: true, sensitivity: 'base' })); + + return repoData; + } catch (error) { - console.log('Using directory scanning fallback'); - await this.scanDirectoryStructure(); + console.error(`Error processing repository ${repoName}:`, error); return null; } } /** - * Fallback method for scanning directory structure - * In a real GitHub Pages environment, we'd need the JSON data file + * Process a single release directory to count assets */ - async scanDirectoryStructure() { - // This is a simplified version that would work if we can list directories - // In a real GitHub Pages environment, we'd need the JSON data file - this.repositoryData = []; + async processRelease(repoName, releaseTag) { + try { + // Get release directory contents + const response = await fetch(`${this.apiBase}/repos/${this.orgName}/packages/contents/${repoName}/${releaseTag}?ref=${this.distBranch}`); + + if (!response.ok) { + console.warn(`Could not fetch release contents for ${repoName}/${releaseTag}: ${response.status}`); + return null; + } + + const contents = await response.json(); + + // Count actual asset files (exclude hash files) + const assetFiles = contents.filter(item => + item.type === 'file' && + !item.name.endsWith('.sha256') && + !item.name.endsWith('.sha512') && + !item.name.endsWith('.md5') && + item.name !== 'README.md' + ); + + if (assetFiles.length === 0) { + return null; + } + + return { + tag: releaseTag, + assetCount: assetFiles.length + }; + + } catch (error) { + console.error(`Error processing release ${repoName}/${releaseTag}:`, error); + return null; + } } /** @@ -76,6 +185,7 @@ class UIManager { this.releaseCountElement = document.getElementById('releaseCount'); this.assetCountElement = document.getElementById('assetCount'); this.updateTimeElement = document.getElementById('updateTime'); + this.orgName = 'LizardByte'; } /** @@ -93,7 +203,8 @@ class UIManager {