diff --git a/.github/scripts/cleanup-releases.js b/.github/scripts/cleanup-releases.js new file mode 100644 index 00000000..7ac3571c --- /dev/null +++ b/.github/scripts/cleanup-releases.js @@ -0,0 +1,48 @@ +const fs = require('fs'); +const path = require('path'); + +/** + * Clean up non-v-prefixed release directories from the dist directory + * @param {string} distPath - Path to the dist directory (default: current directory) + */ +function cleanupNonVPrefixedReleases(distPath = '.') { + console.log('Cleaning up non-v-prefixed release directories...'); + + try { + const distContents = fs.readdirSync(distPath, { withFileTypes: true }); + + for (const dirent of distContents) { + if (dirent.isDirectory() && + dirent.name !== '.git' && + dirent.name !== 'packages.json' && + !dirent.name.startsWith('.')) { + + const repoPath = path.join(distPath, dirent.name); + + try { + const repoContents = fs.readdirSync(repoPath, { withFileTypes: true }); + + for (const releaseDir of repoContents) { + if (releaseDir.isDirectory() && !releaseDir.name.startsWith('v')) { + const releasePath = path.join(repoPath, releaseDir.name); + console.log(`Removing non-v-prefixed release directory: ${releasePath}`); + fs.rmSync(releasePath, { recursive: true, force: true }); + } + } + } catch (repoError) { + console.log(`Error processing repository ${dirent.name}:`, repoError.message); + } + } + } + + console.log('Cleanup completed successfully'); + + } catch (error) { + console.error('Error during cleanup:', error.message); + throw error; + } +} + +module.exports = { + cleanupNonVPrefixedReleases +}; diff --git a/.github/scripts/generate-packages-with-cleanup.js b/.github/scripts/generate-packages-with-cleanup.js new file mode 100644 index 00000000..87c5e194 --- /dev/null +++ b/.github/scripts/generate-packages-with-cleanup.js @@ -0,0 +1,45 @@ +const fs = require('fs'); +const { generatePackagesJson, writePackagesJson } = require('./generate-packages.js'); +const { cleanupNonVPrefixedReleases } = require('./cleanup-releases.js'); + +/** + * Main function to generate packages.json with cleanup + * @param {string} distPath - Path to the dist directory (default: current directory) + */ +function generatePackagesWithCleanup(distPath = '.') { + console.log('Starting packages.json generation process...'); + + try { + // Step 1: Clean up non-v-prefixed release directories + cleanupNonVPrefixedReleases(distPath); + + // Step 2: Read repository metadata from previous step + let repositoryMetadata = []; + const metadataPath = 'repo-metadata.json'; + + try { + const metadataContent = fs.readFileSync(metadataPath, 'utf8'); + repositoryMetadata = JSON.parse(metadataContent); + console.log(`Loaded metadata for ${repositoryMetadata.length} repositories`); + } catch (error) { + console.log('No repository metadata found, continuing without archived status'); + } + + // Step 3: Generate the packages data + const packagesData = generatePackagesJson(distPath, repositoryMetadata); + + // Step 4: Write the packages.json file + writePackagesJson(packagesData, './packages.json'); + + console.log('Packages.json generation completed successfully'); + return packagesData; + + } catch (error) { + console.error('Error during packages.json generation:', error); + throw error; + } +} + +module.exports = { + generatePackagesWithCleanup +}; diff --git a/.github/scripts/generate-packages.js b/.github/scripts/generate-packages.js index 8cb31fa8..23e764fd 100644 --- a/.github/scripts/generate-packages.js +++ b/.github/scripts/generate-packages.js @@ -4,13 +4,20 @@ const path = require('path'); /** * Generate packages.json file by scanning the dist directory structure * @param {string} distPath - Path to the dist directory + * @param {Array} repositoryMetadata - Repository metadata from sync process with archived status * @returns {Object} Generated packages data */ -function generatePackagesJson(distPath = '.') { +function generatePackagesJson(distPath = '.', repositoryMetadata = []) { console.log(`Scanning dist directory: ${distPath}`); const repositories = []; + // Create a map of repository metadata for quick lookup + const repoMetadataMap = new Map(); + repositoryMetadata.forEach(repo => { + repoMetadataMap.set(repo.name, repo); + }); + try { // Read the dist directory const distDir = fs.readdirSync(distPath, { withFileTypes: true }); @@ -21,6 +28,12 @@ function generatePackagesJson(distPath = '.') { console.log(`Processing repository: ${dirent.name}`); const repoData = scanRepositoryDirectory(path.join(distPath, dirent.name)); if (repoData) { + // Update archived status from metadata if available + const metadata = repoMetadataMap.get(dirent.name); + if (metadata) { + repoData.archived = metadata.archived; + } + repositories.push(repoData); console.log(` Found ${repoData.releases.length} releases`); } else { @@ -79,7 +92,7 @@ function scanRepositoryDirectory(repoPath) { const repoDirContents = fs.readdirSync(repoPath, { withFileTypes: true }); for (const dirent of repoDirContents) { - if (dirent.isDirectory()) { + if (dirent.isDirectory() && dirent.name.startsWith('v')) { // Only process v-prefixed releases const releaseData = scanReleaseDirectory(path.join(repoPath, dirent.name)); if (releaseData) { releases.push(releaseData); @@ -93,7 +106,7 @@ function scanRepositoryDirectory(repoPath) { if (releases.length > 0) { return { name: repoName, - archived: false, // Default to false, will be updated by sync process + archived: false, // This will be updated by the sync process with actual GitHub data releases: releases }; } diff --git a/.github/scripts/sync-assets-with-metadata.js b/.github/scripts/sync-assets-with-metadata.js new file mode 100644 index 00000000..dc83b74b --- /dev/null +++ b/.github/scripts/sync-assets-with-metadata.js @@ -0,0 +1,35 @@ +const fs = require('fs'); +const { syncReleaseAssets } = require('./sync-assets.js'); + +/** + * Main function to sync assets and store repository metadata + * @param {Object} github - GitHub API client + * @param {Object} context - GitHub Actions context + * @param {boolean} isPullRequest - Whether this is a pull request event + * @param {number} maxNewAssets - Maximum number of new assets to download + */ +async function syncAssetsWithMetadata(github, context, isPullRequest = false, maxNewAssets = 0) { + console.log('Starting asset synchronization process...'); + + try { + // Run the asset synchronization + const repositoryData = await syncReleaseAssets(github, context, isPullRequest, maxNewAssets); + + // Store repository data for use in next step + const metadataPath = 'repo-metadata.json'; + fs.writeFileSync(metadataPath, JSON.stringify(repositoryData, null, 2)); + + console.log(`Stored metadata for ${repositoryData.length} repositories in ${metadataPath}`); + console.log('Asset synchronization completed successfully'); + + return repositoryData; + + } catch (error) { + console.error('Error during asset synchronization:', error); + throw error; + } +} + +module.exports = { + syncAssetsWithMetadata +}; diff --git a/.github/scripts/sync-assets.js b/.github/scripts/sync-assets.js index 96137905..98357ab8 100644 --- a/.github/scripts/sync-assets.js +++ b/.github/scripts/sync-assets.js @@ -24,8 +24,12 @@ async function processRepository(github, context, repo, repositoryData, totalAss per_page: 100 }); - // Filter out draft and prerelease - const publishedReleases = releases.filter(release => !release.draft && !release.prerelease); + // Filter out draft and prerelease, and only include releases with v-prefixed tags + const publishedReleases = releases.filter(release => + !release.draft && + !release.prerelease && + release.tag_name.startsWith('v') + ); if (publishedReleases.length === 0) { console.log(`No published releases found for ${repo.name}`); @@ -273,6 +277,9 @@ async function syncReleaseAssets(github, context, isPullRequest = false, maxNewA } else { console.log(`Downloaded ${newAssetsDownloaded} new assets`); } + + // Return repository data with archived status + return repositoryData; } module.exports = { diff --git a/.github/workflows/sync-release-assets.yml b/.github/workflows/sync-release-assets.yml index f2768468..6ec52dd4 100644 --- a/.github/workflows/sync-release-assets.yml +++ b/.github/workflows/sync-release-assets.yml @@ -53,8 +53,8 @@ jobs: with: github-token: ${{ secrets.GH_BOT_TOKEN }} script: | - // Import the sync assets module - const { syncReleaseAssets } = require('./.github/scripts/sync-assets.js'); + // Import the sync assets with metadata module + const { syncAssetsWithMetadata } = require('./.github/scripts/sync-assets-with-metadata.js'); // Check if this is a pull request event const isPullRequest = context.eventName === 'pull_request'; @@ -62,10 +62,11 @@ jobs: // Get the max new assets limit from environment const maxNewAssets = parseInt(process.env.MAX_NEW_ASSETS) || 0; - // Run the asset synchronization with PR limit and asset limit // Change working directory to dist for file operations process.chdir('./dist'); - await syncReleaseAssets(github, context, isPullRequest, maxNewAssets); + + // Run the asset synchronization and store metadata + await syncAssetsWithMetadata(github, context, isPullRequest, maxNewAssets); - name: Generate packages.json uses: actions/github-script@v8 @@ -73,18 +74,15 @@ jobs: github-token: ${{ secrets.GH_BOT_TOKEN }} script: | // Import the packages generation module - const { generatePackagesJson, writePackagesJson } = require('./.github/scripts/generate-packages.js'); + const { generatePackagesWithCleanup } = require('./.github/scripts/generate-packages-with-cleanup.js'); console.log('Generating packages.json from dist directory...'); // Change to dist directory process.chdir('./dist'); - // Generate the packages data - const packagesData = generatePackagesJson('.'); - - // Write the packages.json file - writePackagesJson(packagesData, './packages.json'); + // Generate packages.json with cleanup + generatePackagesWithCleanup('.'); - name: Commit and push changes if: github.event_name != 'pull_request' diff --git a/gh-pages-template/assets/js/app.js b/gh-pages-template/assets/js/app.js index 218849ad..1fa4a2ba 100644 --- a/gh-pages-template/assets/js/app.js +++ b/gh-pages-template/assets/js/app.js @@ -84,7 +84,7 @@ class RepositoryDataManager { return filteredRepos.filter(repo => { const repoMatch = repo.name.toLowerCase().includes(searchTerm.toLowerCase()); - const releaseMatch = repo.releases && repo.releases.some(release => + const releaseMatch = repo.releases?.some(release => release.tag.toLowerCase().includes(searchTerm.toLowerCase())); return repoMatch || releaseMatch; }); @@ -115,26 +115,47 @@ class UIManager { return; } - this.repositoryGrid.innerHTML = repos.map(repo => ` -