Skip to content

Commit 6beb81d

Browse files
committed
test: using a pure js zip lib
1 parent 4f10104 commit 6beb81d

File tree

4 files changed

+131
-119
lines changed

4 files changed

+131
-119
lines changed

package.json

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424
"license": "MIT",
2525
"devDependencies": {
2626
"@jsdevtools/ez-spawn": "^3.0.4",
27-
"@types/adm-zip": "^0.5.7",
2827
"@types/node": "^20.14.2",
2928
"@typescript-eslint/eslint-plugin": "^5.62.0",
3029
"@typescript-eslint/parser": "^5.62.0",
@@ -53,7 +52,6 @@
5352
},
5453
"dependencies": {
5554
"@cloudflare/vitest-pool-workers": "^0.6.8",
56-
"adm-zip": "^0.5.16",
5755
"wrangler": "^3.57.1"
5856
},
5957
"packageManager": "pnpm@9.1.3+sha256.7f63001edc077f1cff96cacba901f350796287a2800dfa83fe898f94183e4f5f"

packages/app/package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
"scripts": {
66
"build": "nuxi build",
77
"dev": "nuxi dev",
8+
"preview": "nuxi preview",
89
"generate": "nuxi generate",
910
"vendor:octokit": "tsx script/octokit.ts",
1011
"prepare": "nuxi prepare",
@@ -28,6 +29,7 @@
2829
"@vueuse/core": "^12.2.0",
2930
"@vueuse/nuxt": "^12.2.0",
3031
"chart.js": "^4.5.0",
32+
"fflate": "^0.8.2",
3133
"marked": "^15.0.4",
3234
"nuxt": "^3.15.0",
3335
"nuxt-shiki": "0.3.0",
Lines changed: 95 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { defineEventHandler, H3Event } from "h3";
22
import { useOctokitInstallation } from "../utils/octokit";
3-
import AdmZip from "adm-zip";
3+
import { unzipSync, strFromU8 } from "fflate";
44

55
function extractCountsBlock(content: string): any | null {
66
const lines = content.split("\n");
@@ -30,7 +30,6 @@ function extractCountsBlock(content: string): any | null {
3030
try {
3131
return JSON.parse(block);
3232
} catch (e) {
33-
console.error("Failed to parse Counts block as JSON:", block, e);
3433
return null;
3534
}
3635
}
@@ -40,86 +39,110 @@ let lastFetch = 0;
4039
const CACHE_DURATION = 7 * 24 * 60 * 60 * 1000; // 1 week in ms
4140

4241
export default defineEventHandler(async (event: H3Event) => {
43-
if (cachedData && Date.now() - lastFetch < CACHE_DURATION) {
44-
return cachedData;
45-
}
46-
const owner = "stackblitz-labs";
47-
const repo = "pkg.pr.new";
48-
const workflowId = "stats.yml";
42+
try {
43+
if (cachedData && Date.now() - lastFetch < CACHE_DURATION) {
44+
return cachedData;
45+
}
46+
const owner = "stackblitz-labs";
47+
const repo = "pkg.pr.new";
48+
const workflowId = "stats.yml";
4949

50-
const octokit = await useOctokitInstallation(event, owner, repo);
50+
const octokit = await useOctokitInstallation(event, owner, repo);
5151

52-
const runs = await octokit.paginate(octokit.rest.actions.listWorkflowRuns, {
53-
owner,
54-
repo,
55-
workflow_id: workflowId,
56-
per_page: 100,
57-
status: "success",
58-
});
52+
const runs = await octokit.paginate(octokit.rest.actions.listWorkflowRuns, {
53+
owner,
54+
repo,
55+
workflow_id: workflowId,
56+
per_page: 100,
57+
status: "success",
58+
});
5959

60-
// Only process the latest 100 runs for performance
61-
const latestRuns = runs.slice(0, 100);
60+
// Only process the latest 100 runs for performance
61+
const latestRuns = runs.slice(0, 100);
6262

63-
// 4. For each run, download logs, unzip, and extract Counts
64-
const results = [];
65-
for (const run of latestRuns) {
66-
let stats = null;
67-
try {
68-
const logsResponse = await octokit.rest.actions.downloadWorkflowRunLogs({
69-
owner,
70-
repo,
71-
run_id: run.id,
72-
});
73-
if (logsResponse.status === 302) {
74-
}
75-
if (!logsResponse.data) {
76-
} else {
77-
let buffer;
78-
if (Buffer.isBuffer(logsResponse.data)) {
79-
buffer = logsResponse.data;
80-
} else if (logsResponse.data instanceof ArrayBuffer) {
81-
buffer = Buffer.from(new Uint8Array(logsResponse.data));
63+
// 4. For each run, download logs, unzip, and extract Counts
64+
const results = [];
65+
for (const run of latestRuns) {
66+
let stats = null;
67+
try {
68+
const logsResponse = await octokit.rest.actions.downloadWorkflowRunLogs(
69+
{
70+
owner,
71+
repo,
72+
run_id: run.id,
73+
},
74+
);
75+
if (!logsResponse.data) {
8276
} else {
83-
throw new Error("logsResponse.data is not a Buffer or ArrayBuffer");
84-
}
85-
const zip = new AdmZip(buffer);
86-
const entries = zip.getEntries();
87-
if (entries.length === 0) {
88-
}
89-
let found = false;
90-
for (const entry of entries) {
91-
const content = entry.getData().toString("utf8");
92-
const extracted = extractCountsBlock(content);
93-
if (extracted) {
94-
stats = extracted;
95-
found = true;
96-
break;
77+
let zipData;
78+
if (logsResponse.data instanceof ArrayBuffer) {
79+
zipData = new Uint8Array(logsResponse.data);
80+
} else if (logsResponse.data instanceof Uint8Array) {
81+
zipData = logsResponse.data;
82+
} else if (
83+
typeof Buffer !== "undefined" &&
84+
Buffer.isBuffer(logsResponse.data)
85+
) {
86+
zipData = new Uint8Array(
87+
logsResponse.data.buffer,
88+
logsResponse.data.byteOffset,
89+
logsResponse.data.byteLength,
90+
);
91+
} else {
92+
throw new Error("logsResponse.data is not a supported binary type");
93+
}
94+
let files;
95+
try {
96+
files = unzipSync(zipData);
97+
} catch (e) {
98+
continue;
99+
}
100+
let found = false;
101+
for (const [, fileData] of Object.entries(files)) {
102+
let content;
103+
try {
104+
content = strFromU8(fileData);
105+
} catch (e) {
106+
continue;
107+
}
108+
if (typeof content !== "string" || !content) {
109+
continue;
110+
}
111+
let extracted;
112+
try {
113+
extracted = extractCountsBlock(content);
114+
} catch (e) {
115+
continue;
116+
}
117+
if (extracted) {
118+
stats = extracted;
119+
found = true;
120+
break;
121+
}
97122
}
98123
}
99-
if (!found) {
124+
} catch (e) {
125+
if (
126+
e instanceof Error &&
127+
e.message &&
128+
e.message.includes("Server Error")
129+
) {
130+
// skip
100131
}
101132
}
102-
} catch (e) {
103-
if (
104-
e instanceof Error &&
105-
e.message &&
106-
e.message.includes("Server Error")
107-
) {
108-
// skip
109-
} else {
110-
// console.error(e)
133+
if (stats) {
134+
results.push({
135+
run_number: run.run_number,
136+
created_at: run.created_at,
137+
stats,
138+
});
111139
}
112140
}
113-
if (stats) {
114-
results.push({
115-
run_number: run.run_number,
116-
created_at: run.created_at,
117-
stats,
118-
});
119-
}
141+
// 5. Return JSON
142+
cachedData = { runs: results };
143+
lastFetch = Date.now();
144+
return cachedData;
145+
} catch (err) {
146+
return { error: true, message: String(err), stack: (err as any)?.stack };
120147
}
121-
// 5. Return JSON
122-
cachedData = { runs: results };
123-
lastFetch = Date.now();
124-
return cachedData;
125148
});

0 commit comments

Comments
 (0)