Skip to content

Commit 624fa89

Browse files
committed
feat: add release stats for android
1 parent 8e58d0b commit 624fa89

File tree

2 files changed

+182
-20
lines changed

2 files changed

+182
-20
lines changed

.github/workflows/fetch-release-stats.yml

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,9 @@ jobs:
2626
run: |
2727
cd release_stats && npx tsx fetch-release-stats.ts
2828
29-
- name: Display CSV in summary
29+
- name: Display Desktop CSV in summary
3030
run: |
31-
echo "# Release Download Statistics" >> $GITHUB_STEP_SUMMARY
31+
echo "# Desktop Release Download Statistics" >> $GITHUB_STEP_SUMMARY
3232
echo "" >> $GITHUB_STEP_SUMMARY
3333
echo "**Snapshot Date:** $(date +'%Y-%m-%d %H:%M:%S UTC')" >> $GITHUB_STEP_SUMMARY
3434
echo "" >> $GITHUB_STEP_SUMMARY
@@ -41,14 +41,17 @@ jobs:
4141
print "| " $1 " | " $2 " | " $3 " | " $4 " | " $5 " | " $6 " | " $7 " | " $8 " | " $9 " | " $10 " | " $11 " |"
4242
}' release_stats/session-desktop-release-stats.csv >> $GITHUB_STEP_SUMMARY
4343
44-
- name: Upload CSV artifact
45-
uses: actions/upload-artifact@v4
46-
with:
47-
name: release-stats-${{ github.run_number }}
48-
path: release_stats/session-desktop-release-stats.csv
49-
retention-days: 5
50-
51-
- name: Display CSV preview
44+
- name: Display Android CSV in summary
5245
run: |
53-
echo "CSV Preview:"
54-
head -n 5 release_stats/session-desktop-release-stats.csv
46+
echo "# Android Release Download Statistics" >> $GITHUB_STEP_SUMMARY
47+
echo "" >> $GITHUB_STEP_SUMMARY
48+
echo "**Snapshot Date:** $(date +'%Y-%m-%d %H:%M:%S UTC')" >> $GITHUB_STEP_SUMMARY
49+
echo "" >> $GITHUB_STEP_SUMMARY
50+
51+
# Convert CSV to markdown table
52+
awk -F',' 'NR==1 {
53+
print "| " $1 " | " $2 " | " $3 " | " $4 " | " $5 " | " $6 " | " $7 " | " $8 " | " $9 " | " $10 " | " $11 " |"
54+
print "|---|---|---|---|---|---|---|---|---|---|---|"
55+
} NR>1 {
56+
print "| " $1 " | " $2 " | " $3 " | " $4 " | " $5 " | " $6 " | " $7 " | " $8 " | " $9 " | " $10 " | " $11 " |"
57+
}' release_stats/session-android-release-stats.csv >> $GITHUB_STEP_SUMMARY

release_stats/fetch-release-stats.ts

Lines changed: 167 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ import https from 'https';
22
import fs from 'fs';
33

44
// GitHub API configuration
5-
const REPO = 'session-foundation/session-desktop';
6-
const API_URL = `https://api.github.com/repos/${REPO}/releases`;
5+
const DESKTOP_API_URL = `https://api.github.com/repos/session-foundation/session-desktop/releases`;
6+
const ANDROID_API_URL = `https://api.github.com/repos/session-foundation/session-android/releases`;
77

88
// Types
99
interface Asset {
@@ -17,7 +17,7 @@ interface Release {
1717
assets: Asset[];
1818
}
1919

20-
interface ReleaseStats {
20+
interface DesktopReleaseStats {
2121
version: string;
2222
snapshotDate: string;
2323
dateCaptured: string;
@@ -90,10 +90,10 @@ function getCurrentDate(): string {
9090
}
9191

9292
// Main function
93-
async function generateReleaseStatsCSV(): Promise<void> {
93+
async function generateDesktopReleaseStatsCSV(): Promise<void> {
9494
try {
9595
console.log('Fetching releases from GitHub...');
96-
const releases = await fetchJSON(API_URL);
96+
const releases = await fetchJSON(DESKTOP_API_URL);
9797

9898
// Take only the last 10 releases
9999
const last10Releases = releases.slice(0, 10);
@@ -113,7 +113,7 @@ async function generateReleaseStatsCSV(): Promise<void> {
113113

114114
// Data rows
115115
for (const release of last10Releases) {
116-
const stats: ReleaseStats = {
116+
const stats: DesktopReleaseStats = {
117117
version: release.tag_name.replace(/^v/, ''), // Remove 'v' prefix
118118
snapshotDate: snapshotDate,
119119
dateCaptured: release.published_at.split('T')[0], // Get YYYY-MM-DD
@@ -174,5 +174,164 @@ async function generateReleaseStatsCSV(): Promise<void> {
174174
}
175175
}
176176

177-
// Run the script
178-
generateReleaseStatsCSV();
177+
// Android-specific types
178+
interface AndroidReleaseStats {
179+
version: string;
180+
snapshotDate: string;
181+
dateCaptured: string;
182+
aabDownloads: number;
183+
apkArm64Downloads: number;
184+
apkArmv7aDownloads: number;
185+
apkUniversalHuaweiDownloads: number;
186+
apkUniversalPlayDownloads: number;
187+
apkX86Downloads: number;
188+
apkX86_64Downloads: number;
189+
}
190+
191+
// Helper function to count downloads for Android APKs with specific architecture
192+
function countAndroidDownloadsByPattern(
193+
assets: any[],
194+
extension: string,
195+
architecture: string,
196+
buildType: string = 'play-release'
197+
): number {
198+
return assets
199+
.filter(
200+
(asset) =>
201+
asset.name.endsWith(extension) &&
202+
asset.name.includes(architecture) &&
203+
asset.name.includes(buildType)
204+
)
205+
.reduce((sum, asset) => sum + asset.download_count, 0);
206+
}
207+
208+
// Helper function for AAB files
209+
function countAABDownloads(assets: any[]): number {
210+
return assets
211+
.filter(
212+
(asset) =>
213+
asset.name.endsWith('.aab') && asset.name.includes('play-release')
214+
)
215+
.reduce((sum, asset) => sum + asset.download_count, 0);
216+
}
217+
218+
// Helper function for universal APKs
219+
function countUniversalAPKDownloads(
220+
assets: any[],
221+
storeType: 'play' | 'huawei'
222+
): number {
223+
return assets
224+
.filter(
225+
(asset) =>
226+
asset.name.endsWith('.apk') &&
227+
asset.name.includes('universal') &&
228+
asset.name.includes(`${storeType}-release`)
229+
)
230+
.reduce((sum, asset) => sum + asset.download_count, 0);
231+
}
232+
233+
// Helper function to count downloads for x86 (excluding x86_64)
234+
function countX86Downloads(assets: any[]): number {
235+
return assets
236+
.filter(
237+
(asset) =>
238+
asset.name.endsWith('.apk') &&
239+
asset.name.includes('x86') &&
240+
!asset.name.includes('x86_64') && // Explicitly exclude x86_64
241+
asset.name.includes('play-release')
242+
)
243+
.reduce((sum, asset) => sum + asset.download_count, 0);
244+
}
245+
246+
// Main function for Android releases
247+
async function generateAndroidReleaseStatsCSV(): Promise<void> {
248+
try {
249+
console.log('Fetching releases from GitHub...');
250+
const releases = await fetchJSON(ANDROID_API_URL);
251+
252+
// Take only the last 10 releases
253+
const last10Releases = releases.slice(0, 10);
254+
255+
console.log(`Processing ${last10Releases.length} releases...`);
256+
257+
const snapshotDate = getCurrentDate();
258+
console.log(`Snapshot date: ${snapshotDate}`);
259+
260+
// Build CSV data
261+
const csvRows: string[] = [];
262+
263+
// Header row
264+
csvRows.push(
265+
'version,snapshot_date,release_date,.aab,.apk_arm64,.apk_armv7a,.apk_universal_huawei,.apk_universal_play,.apk_x86,.apk_x86_64'
266+
);
267+
268+
// Data rows
269+
for (const release of last10Releases) {
270+
const stats: AndroidReleaseStats = {
271+
version: release.tag_name.replace(/^v/, ''),
272+
snapshotDate: snapshotDate,
273+
dateCaptured: release.published_at.split('T')[0],
274+
aabDownloads: countAABDownloads(release.assets),
275+
apkArm64Downloads: countAndroidDownloadsByPattern(
276+
release.assets,
277+
'.apk',
278+
'arm64-v8a'
279+
),
280+
apkArmv7aDownloads: countAndroidDownloadsByPattern(
281+
release.assets,
282+
'.apk',
283+
'armeabi-v7a'
284+
),
285+
apkUniversalHuaweiDownloads: countUniversalAPKDownloads(
286+
release.assets,
287+
'huawei'
288+
),
289+
apkUniversalPlayDownloads: countUniversalAPKDownloads(
290+
release.assets,
291+
'play'
292+
),
293+
apkX86Downloads: countX86Downloads(release.assets), // Use the dedicated function
294+
apkX86_64Downloads: countAndroidDownloadsByPattern(
295+
release.assets,
296+
'.apk',
297+
'x86_64'
298+
),
299+
};
300+
301+
csvRows.push(
302+
[
303+
stats.version,
304+
stats.snapshotDate,
305+
stats.dateCaptured,
306+
stats.aabDownloads,
307+
stats.apkArm64Downloads,
308+
stats.apkArmv7aDownloads,
309+
stats.apkUniversalHuaweiDownloads,
310+
stats.apkUniversalPlayDownloads,
311+
stats.apkX86Downloads,
312+
stats.apkX86_64Downloads,
313+
].join(',')
314+
);
315+
}
316+
317+
// Write to file
318+
const csvContent = csvRows.join('\n');
319+
const filename = 'session-android-release-stats.csv';
320+
321+
fs.writeFileSync(filename, csvContent);
322+
323+
console.log(`\nCSV file generated: ${filename}`);
324+
console.log(`Total releases processed: ${last10Releases.length}`);
325+
console.log('\nFull content:');
326+
console.log(csvRows.join('\n'));
327+
} catch (error) {
328+
console.error(
329+
'Error:',
330+
error instanceof Error ? error.message : 'Unknown error'
331+
);
332+
process.exit(1);
333+
}
334+
}
335+
336+
generateDesktopReleaseStatsCSV();
337+
generateAndroidReleaseStatsCSV();

0 commit comments

Comments
 (0)