Skip to content

Commit 4cd7838

Browse files
committed
2 parents 3853126 + 86136ee commit 4cd7838

12 files changed

Lines changed: 472 additions & 48 deletions

File tree

.github/scripts/check-updates.mjs

Lines changed: 224 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,224 @@
1+
import { Octokit } from "@octokit/rest";
2+
import fs from 'fs';
3+
import path from 'path';
4+
5+
const octokit = new Octokit({
6+
auth: process.env.GITHUB_TOKEN,
7+
});
8+
9+
async function getLatestCommit(owner, repo, filePath = '') {
10+
try {
11+
const response = await octokit.rest.repos.listCommits({
12+
owner,
13+
repo,
14+
path: filePath,
15+
per_page: 1
16+
});
17+
return response.data[0];
18+
} catch (error) {
19+
console.error(`❌ Error fetching commits for ${owner}/${repo}: ${error.message}`);
20+
return null;
21+
}
22+
}
23+
24+
async function getFileChanges(owner, repo, oldCommit, newCommit, filePaths) {
25+
try {
26+
const comparison = await octokit.rest.repos.compareCommits({
27+
owner,
28+
repo,
29+
base: oldCommit,
30+
head: newCommit
31+
});
32+
33+
const relevantFiles = comparison.data.files.filter(file =>
34+
filePaths.some(trackPath => {
35+
const normalizedTrackPath = trackPath.startsWith('/') ? trackPath.slice(1) : trackPath;
36+
return file.filename.includes(normalizedTrackPath) ||
37+
normalizedTrackPath.includes(file.filename);
38+
})
39+
);
40+
41+
return {
42+
totalChanges: comparison.data.files.length,
43+
relevantChanges: relevantFiles.length,
44+
files: relevantFiles.map(file => ({
45+
filename: file.filename,
46+
status: file.status,
47+
additions: file.additions,
48+
deletions: file.deletions,
49+
patch: file.patch
50+
}))
51+
};
52+
} catch (error) {
53+
console.error(`❌ Error comparing commits: ${error.message}`);
54+
return null;
55+
}
56+
}
57+
58+
function findMetadataFiles(dir) {
59+
const metadataFiles = [];
60+
61+
function searchRecursively(currentDir) {
62+
const entries = fs.readdirSync(currentDir, { withFileTypes: true });
63+
64+
for (const entry of entries) {
65+
const fullPath = path.join(currentDir, entry.name);
66+
67+
if (entry.isDirectory()) {
68+
searchRecursively(fullPath);
69+
} else if (entry.name === 'metadata.json') {
70+
metadataFiles.push(fullPath);
71+
}
72+
}
73+
}
74+
75+
searchRecursively(dir);
76+
return metadataFiles;
77+
}
78+
79+
async function main() {
80+
console.log('🔍 Starting metadata update check...\n');
81+
82+
const metadataFiles = findMetadataFiles('./repositories');
83+
console.log(`📁 Found ${metadataFiles.length} metadata files\n`);
84+
85+
let totalChecked = 0;
86+
let updatesAvailable = 0;
87+
let errors = 0;
88+
89+
const detailedOutput = process.env.DETAILED_OUTPUT === 'true';
90+
const onlyShowUpdates = process.env.ONLY_SHOW_UPDATES === 'true';
91+
92+
for (const metadataFile of metadataFiles) {
93+
try {
94+
totalChecked++;
95+
const metadata = JSON.parse(fs.readFileSync(metadataFile, 'utf8'));
96+
97+
// Skip showing repository info if only showing updates and this repo is up to date
98+
const shouldShowBasicInfo = !onlyShowUpdates;
99+
100+
if (shouldShowBasicInfo) {
101+
console.log(`📦 Checking: ${metadata.name} (${metadata.owner}/${metadata.repo})`);
102+
console.log(` Repository: https://github.com/${metadata.owner}/${metadata.repo}`);
103+
console.log(` Current commit: ${metadata.commit}`);
104+
console.log(` Path: ${metadata.path || '/'}`);
105+
}
106+
107+
// Get latest commit from the repository
108+
const latestCommit = await getLatestCommit(
109+
metadata.owner,
110+
metadata.repo,
111+
metadata.path
112+
);
113+
114+
if (!latestCommit) {
115+
if (shouldShowBasicInfo) {
116+
console.log(` ❌ Could not fetch latest commit\n`);
117+
}
118+
errors++;
119+
continue;
120+
}
121+
122+
if (shouldShowBasicInfo) {
123+
console.log(` Latest commit: ${latestCommit.sha}`);
124+
console.log(` Latest commit date: ${latestCommit.commit.committer.date}`);
125+
console.log(` Latest commit message: "${latestCommit.commit.message.split('\n')[0]}"`);
126+
}
127+
128+
if (metadata.commit === latestCommit.sha) {
129+
if (!onlyShowUpdates) {
130+
console.log(` ✅ Up to date\n`);
131+
}
132+
} else {
133+
// Get file paths to track
134+
let filePaths = [];
135+
if (Array.isArray(metadata.files)) {
136+
filePaths = metadata.files.map(file => {
137+
if (typeof file === 'string') {
138+
return path.join(metadata.path || '/', file).replace(/\\/g, '/');
139+
} else if (file.source) {
140+
return path.join(metadata.path || '/', file.source).replace(/\\/g, '/');
141+
}
142+
return '';
143+
}).filter(p => p);
144+
}
145+
146+
// Check if tracked files have actually changed
147+
let hasRelevantChanges = false;
148+
let changes = null;
149+
150+
if (filePaths.length > 0) {
151+
changes = await getFileChanges(
152+
metadata.owner,
153+
metadata.repo,
154+
metadata.commit,
155+
latestCommit.sha,
156+
filePaths
157+
);
158+
159+
if (changes && changes.relevantChanges > 0) {
160+
hasRelevantChanges = true;
161+
}
162+
} else {
163+
// If no specific files to track, assume any commit means changes
164+
hasRelevantChanges = true;
165+
}
166+
167+
if (!hasRelevantChanges) {
168+
if (!onlyShowUpdates) {
169+
console.log(` ✅ Up to date (no relevant file changes)\n`);
170+
}
171+
} else {
172+
// Always show update available info, regardless of onlyShowUpdates setting
173+
if (onlyShowUpdates) {
174+
console.log(`📦 Checking: ${metadata.name} (${metadata.owner}/${metadata.repo})`);
175+
console.log(` Repository: https://github.com/${metadata.owner}/${metadata.repo}`);
176+
console.log(` Current commit: ${metadata.commit}`);
177+
console.log(` Latest commit: ${latestCommit.sha}`);
178+
console.log(` Latest commit date: ${latestCommit.commit.committer.date}`);
179+
console.log(` Latest commit message: "${latestCommit.commit.message.split('\n')[0]}"`);
180+
}
181+
console.log(` 🔄 UPDATE AVAILABLE!`);
182+
console.log(` 📄 Compare commits: https://github.com/${metadata.owner}/${metadata.repo}/compare/${metadata.commit}...${latestCommit.sha}`);
183+
updatesAvailable++;
184+
185+
// Get detailed changes if requested
186+
if (detailedOutput && changes) {
187+
console.log(` 📊 Total repository changes: ${changes.totalChanges} files`);
188+
console.log(` 📊 Relevant file changes: ${changes.relevantChanges} files`);
189+
190+
if (changes.files.length > 0) {
191+
console.log(` 📄 Changed files:`);
192+
for (const file of changes.files) {
193+
console.log(` - ${file.filename} (${file.status}) [+${file.additions}/-${file.deletions}]`);
194+
}
195+
}
196+
}
197+
console.log('');
198+
}
199+
}
200+
201+
// Small delay to avoid rate limiting
202+
await new Promise(resolve => setTimeout(resolve, 100));
203+
204+
} catch (error) {
205+
console.error(`❌ Error processing ${metadataFile}: ${error.message}\n`);
206+
errors++;
207+
}
208+
}
209+
210+
console.log('📊 SUMMARY:');
211+
console.log(` Total metadata files checked: ${totalChecked}`);
212+
console.log(` Updates available: ${updatesAvailable}`);
213+
console.log(` Errors: ${errors}`);
214+
console.log(` Up to date: ${totalChecked - updatesAvailable - errors}`);
215+
216+
if (updatesAvailable > 0) {
217+
console.log(`\n🎯 ${updatesAvailable} repositories have updates available!`);
218+
process.exit(0); // Don't fail the workflow, just inform
219+
} else {
220+
console.log('\n✅ All repositories are up to date!');
221+
}
222+
}
223+
224+
main().catch(console.error);
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
name: Check Metadata Updates
2+
3+
on:
4+
workflow_dispatch:
5+
inputs:
6+
detailed_output:
7+
description: 'Show detailed file changes'
8+
required: false
9+
default: true
10+
type: boolean
11+
only_show_updates:
12+
description: 'Only show repositories with updates available'
13+
required: false
14+
default: true
15+
type: boolean
16+
17+
jobs:
18+
check-updates:
19+
runs-on: ubuntu-latest
20+
21+
steps:
22+
- name: Checkout repository
23+
uses: actions/checkout@v4
24+
with:
25+
fetch-depth: 0
26+
27+
- name: Setup Node.js
28+
uses: actions/setup-node@v4
29+
with:
30+
node-version: '18'
31+
32+
- name: Install dependencies
33+
run: |
34+
npm install @octokit/rest
35+
npm install axios
36+
37+
- name: Check metadata for updates
38+
env:
39+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
40+
DETAILED_OUTPUT: ${{ inputs.detailed_output }}
41+
ONLY_SHOW_UPDATES: ${{ inputs.only_show_updates }}
42+
run: node .github/scripts/check-updates.mjs

.github/workflows/deploy-pages.yml

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
name: Deploy to GitHub Pages
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
paths:
8+
- '*.json'
9+
workflow_run:
10+
workflows: ["Generate Release Files"]
11+
types:
12+
- completed
13+
branches:
14+
- main
15+
workflow_dispatch:
16+
17+
permissions:
18+
contents: read
19+
pages: write
20+
id-token: write
21+
22+
concurrency:
23+
group: "pages"
24+
cancel-in-progress: false
25+
26+
jobs:
27+
build:
28+
runs-on: ubuntu-latest
29+
# Only run if workflow_run was successful or if triggered by push/manual
30+
if: github.event_name != 'workflow_run' || github.event.workflow_run.conclusion == 'success'
31+
steps:
32+
- name: Checkout
33+
uses: actions/checkout@v4
34+
with:
35+
fetch-depth: 0
36+
37+
- name: Setup Pages
38+
uses: actions/configure-pages@v4
39+
40+
- name: Build with Jekyll
41+
uses: actions/jekyll-build-pages@v1
42+
with:
43+
source: ./
44+
destination: ./_site
45+
46+
- name: Upload artifact
47+
uses: actions/upload-pages-artifact@v3
48+
49+
deploy:
50+
environment:
51+
name: github-pages
52+
url: ${{ steps.deployment.outputs.page_url }}
53+
runs-on: ubuntu-latest
54+
needs: build
55+
steps:
56+
- name: Deploy to GitHub Pages
57+
id: deployment
58+
uses: actions/deploy-pages@v4

.github/workflows/generate-releases.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ on:
44
push:
55
branches:
66
- main
7+
paths:
8+
- 'releases/**'
9+
- 'repositories/**'
10+
- '*.json'
711
workflow_dispatch:
812

913
permissions:

releases/categories.json

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"totalCategories": 8,
3-
"totalApps": 56,
3+
"totalApps": 58,
44
"categories": [
55
{
66
"name": "Audio",
@@ -24,13 +24,13 @@
2424
"name": "RF",
2525
"slug": "rf",
2626
"count": 2,
27-
"lastUpdated": 1771432175
27+
"lastUpdated": 1772244104
2828
},
2929
{
3030
"name": "Themes",
3131
"slug": "themes",
32-
"count": 28,
33-
"lastUpdated": 1771972336
32+
"count": 30,
33+
"lastUpdated": 1772535826
3434
},
3535
{
3636
"name": "Tools",
@@ -48,7 +48,7 @@
4848
"name": "WiFi",
4949
"slug": "wifi",
5050
"count": 1,
51-
"lastUpdated": 1770902136
51+
"lastUpdated": 1772244104
5252
}
5353
]
5454
}

0 commit comments

Comments
 (0)