diff --git a/e2e/publish.test.mts b/e2e/publish.test.mts index 7719dba7..920f3e40 100644 --- a/e2e/publish.test.mts +++ b/e2e/publish.test.mts @@ -75,20 +75,28 @@ await wp({ port: PORT }); { // install - const playgroundUrl = new URL('/stackblitz-labs/stackblitz-ci/main/41cc8072abe146bb7eddc4b39de644a77acd1e9d/playground', serverUrl) + const playgroundShaUrl = new URL('/stackblitz-labs/stackblitz-ci/main/41cc8072abe146bb7eddc4b39de644a77acd1e9d/playground', serverUrl) { - const data = await fetch(playgroundUrl, { + const playgroundShaData = await fetch(playgroundShaUrl, { method: 'GET', }) - const blob =await data.blob() - console.log(blob) - assert.ok(!!blob.size, "playground size should not be zero") - assert.equal(data.status, 200, "playground response should be 200") + const playgroundShaBlob =await playgroundShaData.blob() + console.log(playgroundShaBlob) + assert.ok(!!playgroundShaBlob.size, "playground size should not be zero") + assert.equal(playgroundShaData.status, 200, "playground response should be 200") + + // const playgroundWithoutShaUrl = new URL('/stackblitz-labs/stackblitz-ci/main/playground', serverUrl) + // const playgroundWithoutShaData = await fetch(playgroundWithoutShaUrl, { + // method: 'GET', + // }) + // const playgroundWithoutShaBlob = await playgroundWithoutShaData.blob() + // console.log('sha url and non-sha url', playgroundShaBlob.arrayBuffer, playgroundWithoutShaBlob.arrayBuffer) + // assert.deepEqual(await playgroundShaBlob.arrayBuffer(), await playgroundWithoutShaBlob.arrayBuffer(), "sha urls and non-sha urls should not give different results") } { - playgroundUrl.searchParams.set('id', Date.now().toString()) - const playgroundProcess = await ezSpawn.async(`yes | npx -f playground@${playgroundUrl}`,{ + playgroundShaUrl.searchParams.set('id', Date.now().toString()) + const playgroundProcess = await ezSpawn.async(`yes | npx -f playground@${playgroundShaUrl}`,{ stdio: 'overlapped', shell: true, }) diff --git a/packages/backend/nitro.config.ts b/packages/backend/nitro.config.ts index 10b5fab2..ba491a8f 100644 --- a/packages/backend/nitro.config.ts +++ b/packages/backend/nitro.config.ts @@ -38,4 +38,6 @@ export default defineNitroConfig({ privateKey: "", test: "", }, + + timing: true }); diff --git a/packages/backend/server/octokit.ts b/packages/backend/server/octokit.ts index ecc20d2f..590214ab 100644 --- a/packages/backend/server/octokit.ts +++ b/packages/backend/server/octokit.ts @@ -26,7 +26,6 @@ import { Octokit as OctokitCore } from "@octokit/core"; import { createAppAuth } from "@octokit/auth-app"; import { OAuthApp } from "@octokit/oauth-app"; import { Webhooks, type EmitterWebhookEvent } from "@octokit/webhooks"; -console.log('here') type Constructor = new (...args: any[]) => T; diff --git a/packages/backend/server/routes/[orgOrAuthor]/[repo]/[ref]/[package].get.ts b/packages/backend/server/routes/[orgOrAuthor]/[repo]/[ref]/[package].get.ts new file mode 100644 index 00000000..c5caa606 --- /dev/null +++ b/packages/backend/server/routes/[orgOrAuthor]/[repo]/[ref]/[package].get.ts @@ -0,0 +1,27 @@ +import { objectHash, sha256 } from "ohash"; +import { WorkflowData } from "../../../../types"; + +type Params = Omit & { + package: string; +}; + +export default eventHandler(async (event) => { + const params = getRouterParams(event) as Params; + const packagesBucket = usePackagesBucket(); + + const { package: packageName, ...hashPrefixMetadata } = params; + const metadataHash = sha256(objectHash(hashPrefixMetadata)); + const keys = await packagesBucket.getKeys(metadataHash) + console.log(keys) + // const packageKey = `${metadataHash}:${sha}:${packageName.split('.tgz')[0]}`; + // if (!(await packagesBucket.hasItem(packageKey))) { + // throw createError({ + // status: 404, + // }); + // } + // const buffer = await packagesBucket.getItemRaw(packageKey); + + // setResponseHeader(event, "content-type", "application/tar+gzip"); + // // add caching + // return new Response(buffer); +}); diff --git a/packages/backend/server/routes/[orgOrAuthor]/[repo]/[ref]/[sha]/[package].get.ts b/packages/backend/server/routes/[orgOrAuthor]/[repo]/[ref]/[sha]/[package].get.ts index fad046a1..79f9acd5 100644 --- a/packages/backend/server/routes/[orgOrAuthor]/[repo]/[ref]/[sha]/[package].get.ts +++ b/packages/backend/server/routes/[orgOrAuthor]/[repo]/[ref]/[sha]/[package].get.ts @@ -18,7 +18,6 @@ export default eventHandler(async (event) => { }); } const buffer = await packagesBucket.getItemRaw(packageKey); - console.log("buffer", buffer); setResponseHeader(event, "content-type", "application/tar+gzip"); // add caching diff --git a/packages/backend/server/routes/publish.post.ts b/packages/backend/server/routes/publish.post.ts index b282e638..ba4d8682 100644 --- a/packages/backend/server/routes/publish.post.ts +++ b/packages/backend/server/routes/publish.post.ts @@ -1,4 +1,5 @@ import { objectHash, sha256 } from "ohash"; +import {generateCommitPublishMessage} from '../utils/markdown' export default eventHandler(async (event) => { const contentLength = Number(getHeader(event, "content-length")); @@ -16,21 +17,33 @@ export default eventHandler(async (event) => { } const binary = await readRawBody(event, false); - const { - "sb-package-name": packageName, - "sb-package-version": _, - } = getHeaders(event); + const { "sb-package-name": packageName, "sb-package-version": _ } = + getHeaders(event); const workflowData = await workflowsBucket.getItem(key); const { sha, ...hashPrefixMetadata } = workflowData; const metadataHash = sha256(objectHash(hashPrefixMetadata)); const packageKey = `${metadataHash}:${sha}:${packageName}`; - console.log(hashPrefixMetadata) - console.log('publish packageKey', packageKey) await packagesBucket.setItemRaw(packageKey, binary); await workflowsBucket.removeItem(key); + const app = useOctokitApp(event); + const origin = getRequestURL(event).origin + + app.octokit.request("POST /repos/{owner}/{repo}/check-runs", { + name: "Stackblitz CR (Publish)", + owner: workflowData.orgOrAuthor, + repo: workflowData.repo, + head_sha: sha, + output: { + title: 'Stackblitz CR', + summary: 'Published successfully.', + text: generateCommitPublishMessage(origin, packageName, workflowData) + }, + conclusion: "success", + }); + return { ok: true }; }); diff --git a/packages/backend/server/routes/webhook.post.ts b/packages/backend/server/routes/webhook.post.ts index f02cf8c4..70c933d1 100644 --- a/packages/backend/server/routes/webhook.post.ts +++ b/packages/backend/server/routes/webhook.post.ts @@ -1,12 +1,12 @@ import type { HandlerFunction } from "@octokit/webhooks/dist-types/types"; import type { WorkflowData } from "../types"; -import { hash, objectHash, sha256 } from "ohash"; +import { hash } from "ohash"; export default eventHandler(async (event) => { const app = useOctokitApp(event) const { test } = useRuntimeConfig(event) - const { setItem, removeItem, getItem } = useWorkflowsBucket(); + const { setItem, removeItem } = useWorkflowsBucket(); const workflowHandler: HandlerFunction<"workflow_job", unknown> = async ({ payload, @@ -17,7 +17,6 @@ export default eventHandler(async (event) => { actor: payload.sender.id, }; const key = hash(metadata); - console.log('webhook', metadata, key) if (payload.action === "queued") { const [orgOrAuthor, repo] = payload.repository.full_name.split("/"); const data: WorkflowData = { diff --git a/packages/backend/server/utils/markdown.ts b/packages/backend/server/utils/markdown.ts new file mode 100644 index 00000000..11fcf870 --- /dev/null +++ b/packages/backend/server/utils/markdown.ts @@ -0,0 +1,24 @@ +import { WorkflowData } from "../types"; + +export function generateCommitPublishMessage( + origin: string, + packageName: string, + workflowData: WorkflowData +) { + console.log(origin, workflowData) + const url = new URL( + `/${workflowData.orgOrAuthor}/${workflowData.repo}/${workflowData.ref}/${workflowData.sha}/${packageName}`, + origin + ); + return ` + +${url} + + +
Commit: +${workflowData.sha} +
+ +npm i ${url} + `; +}