Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 48 additions & 0 deletions .github/scripts/cleanup-releases.js
Original file line number Diff line number Diff line change
@@ -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
};
45 changes: 45 additions & 0 deletions .github/scripts/generate-packages-with-cleanup.js
Original file line number Diff line number Diff line change
@@ -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
};
19 changes: 16 additions & 3 deletions .github/scripts/generate-packages.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 });
Expand All @@ -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 {
Expand Down Expand Up @@ -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);
Expand All @@ -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
};
}
Expand Down
35 changes: 35 additions & 0 deletions .github/scripts/sync-assets-with-metadata.js
Original file line number Diff line number Diff line change
@@ -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
};
11 changes: 9 additions & 2 deletions .github/scripts/sync-assets.js
Original file line number Diff line number Diff line change
Expand Up @@ -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}`);
Expand Down Expand Up @@ -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 = {
Expand Down
18 changes: 8 additions & 10 deletions .github/workflows/sync-release-assets.yml
Original file line number Diff line number Diff line change
Expand Up @@ -53,38 +53,36 @@ 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';

// 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
with:
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'
Expand Down
65 changes: 43 additions & 22 deletions gh-pages-template/assets/js/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
});
Expand Down Expand Up @@ -115,26 +115,47 @@ class UIManager {
return;
}

this.repositoryGrid.innerHTML = repos.map(repo => `
<div class="col-lg-4 col-md-6 mb-4" data-repo="${repo.name.toLowerCase()}">
<div class="card h-100 shadow border-0 rounded-0">
<div class="card-body text-white p-4 rounded-0">
<h5 class="card-title text-info mb-3">${repo.name}</h5>
<ul class="list-group list-group-flush">
${repo.releases ? repo.releases.map(release => `
<li class="list-group-item d-flex justify-content-between align-items-center px-0">
<a href="https://github.com/${this.orgName}/packages/tree/dist/${repo.name}/${release.tag}"
class="text-decoration-none fw-medium" target="_blank" rel="noopener">
${release.tag}
</a>
<span class="badge bg-secondary rounded-pill">${release.assetCount}</span>
</li>
`).join('') : '<li class="list-group-item">No releases found</li>'}
</ul>
this.repositoryGrid.innerHTML = repos.map(repo => {
// Show only the latest 5 releases
const displayReleases = repo.releases ? repo.releases.slice(0, 5) : [];
const hasMoreReleases = repo.releases && repo.releases.length > 5;
const remainingCount = hasMoreReleases ? repo.releases.length - 5 : 0;

// Extract ternary operation for better readability
const releaseText = remainingCount > 1 ? 's' : '';

return `
<div class="col-lg-4 col-md-6 mb-4" data-repo="${repo.name.toLowerCase()}" ${repo.archived ? 'data-archived="true"' : ''}>
<div class="card h-100 shadow border-0 rounded-0">
<div class="card-body text-white p-4 rounded-0">
<h5 class="card-title text-info mb-3">
${repo.name}
${repo.archived ? '<span class="badge bg-warning text-dark ms-2">Archived</span>' : ''}
</h5>
<ul class="list-group list-group-flush">
${displayReleases.length > 0 ? displayReleases.map(release => `
<li class="list-group-item d-flex justify-content-between align-items-center px-0">
<a href="https://github.com/${this.orgName}/packages/tree/dist/${repo.name}/${release.tag}"
class="text-decoration-none fw-medium" target="_blank" rel="noopener">
${release.tag}
</a>
<span class="badge bg-secondary rounded-pill">${release.assetCount}</span>
</li>
`).join('') : '<li class="list-group-item">No releases found</li>'}
${hasMoreReleases ? `
<li class="list-group-item px-0 text-center">
<a href="https://github.com/${this.orgName}/packages/tree/dist/${repo.name}"
class="btn btn-outline-primary btn-sm" target="_blank" rel="noopener">
Show ${remainingCount} more release${releaseText}
</a>
</li>
` : ''}
</ul>
</div>
</div>
</div>
</div>
`).join('');
`;
}).join('');
}

/**
Expand Down Expand Up @@ -233,8 +254,8 @@ class LizardByteAssetsApp {
// Show loading state
this.uiManager.showLoading();

// Load repository data
const data = await this.dataManager.loadRepositoryData();
// Load repository data from packages.json
await this.dataManager.loadRepositoryData();
const repositories = this.dataManager.getRepositories();

// Render repositories and update stats
Expand All @@ -249,7 +270,7 @@ class LizardByteAssetsApp {
} catch (error) {
console.error('Failed to initialize application:', error);
this.uiManager.repositoryGrid.innerHTML =
'<div class="no-results">Failed to load repository data. Please try again later.</div>';
'<div class="col-12 text-center fst-italic py-5">Failed to load repository data. Please try again later.</div>';
}
}
}
Expand Down