-
Notifications
You must be signed in to change notification settings - Fork 22
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
chore(ci): introduce benchmarks on JS/TS projects to track skott perf…
…ormance over time (#145) * feat(remote-tarball-fetcher): add github fetcher * bench: add vitest benchmark with few js and ts projects * fix: properly extract tar and zip artifacts * refactor: extract util for web streams to nodejs streams * feat: use GITHUB_TOKEN to avoid rate limiting in CI * refactor: customize benchmark output * ci: run benchmark for skott * chore: scope benchmark only for ubuntu runners * chore(ci): run the benchmark with a publish of the result only in the context of a feat branch * get rid of benchmarks in ci * chore: add changeset * docs: update pull_request_template * ci: enable bench * benchmark: publish results * Add node version to benchmark * benchmark: publish results * Add node version to benchmark * benchmark: publish benchmark results from node_20.x * benchmark: publish benchmark results from node_18.x * ci: add github sha and ref * benchmark: publish benchmark results from node_20.x * benchmark: publish benchmark results from node_20.x * benchmark: publish benchmark results from node_20.x * benchmark: publish benchmark results from node_20.x * benchmark: publish benchmark results from node_20.x * fetch origin before * benchmark: publish benchmark results from node_20.x * use checkout v4 * benchmark: publish benchmark results from node_20.x * use checkout v4 * benchmark: publish benchmark results from node_20.x * use checkout v4 * benchmark: publish benchmark results from node_20.x * use checkout v4 * benchmark: publish benchmark results from node_20.x * use checkout v4 * benchmark: publish benchmark results from node_20.x * benchmark: publish benchmark results from node_18.x * benchmark: publish benchmark results from node_20.x * benchmark: publish benchmark results from node_18.x * benchmark: publish benchmark results from node_18.x * benchmark: publish benchmark results from node_20.x * benchmark: publish benchmark results from node_18.x * debug env * benchmark: publish benchmark results from node_20.x * benchmark: publish benchmark results from node_18.x * debug env * benchmark: publish benchmark results from node_20.x * benchmark: publish benchmark results from node_18.x * ci: constrain benchmark run * benchmark: publish benchmark results from node_20.x * benchmark: publish benchmark results from node_18.x --------- Co-authored-by: skott_benchmark <skott.devtool@gmail.com>
- Loading branch information
1 parent
e0e3ba1
commit 2c00723
Showing
25 changed files
with
1,262 additions
and
458 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
--- | ||
"remote-tarball-fetcher": minor | ||
--- | ||
|
||
Add GitHub tarball fetcher to be able to pull public repositories as `.zip` (used in skott's benchmark). | ||
|
||
Switch to an [Effect](https://github.com/Effect-TS)-based API. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
import type { ReadableStream } from "node:stream/web"; | ||
|
||
import { Effect, Option } from "effect"; | ||
|
||
export interface PackageInformation { | ||
id: string; | ||
tarballUrl: string; | ||
} | ||
|
||
export class FetchPackageInformationError { | ||
readonly _tag = "FetchPackageInformationError"; | ||
} | ||
|
||
export interface Fetcher<AdditionalInformation = Record<string, string>> { | ||
fetchPackageInformation: ( | ||
libraryName: string | ||
) => Effect.Effect< | ||
PackageInformation & AdditionalInformation, | ||
FetchPackageInformationError | ||
>; | ||
downloadTarball: (tarballUrl: string) => Effect.Effect< | ||
Option.Option<{ | ||
stream: ReadableStream; | ||
format: "zip" | "tar"; | ||
}> | ||
>; | ||
} |
48 changes: 48 additions & 0 deletions
48
packages/remote-tarball-fetcher/src/fetcher/github.integration.spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
import { ReadableStream } from "node:stream/web"; | ||
|
||
import { expect } from "chai"; | ||
import { Effect, Option, pipe } from "effect"; | ||
|
||
import { githubFetcher } from "./github.js"; | ||
|
||
function itEffect<A, E>( | ||
description: string, | ||
effect: Effect.Effect<A, E, never> | ||
) { | ||
it(description, () => effect.pipe(Effect.runPromise)); | ||
} | ||
|
||
describe("GitHub integration", () => { | ||
describe("When fetching skott tarball", () => { | ||
itEffect( | ||
"Should fetch the tarball from the main branch", | ||
Effect.gen(function* gen(_) { | ||
const fetcher = githubFetcher; | ||
|
||
const { id, defaultBranch, tarballUrl } = yield* _( | ||
fetcher.fetchPackageInformation("antoine-coulon/skott") | ||
); | ||
|
||
expect(id).to.be.a("string"); | ||
expect({ defaultBranch, tarballUrl }).to.deep.equal({ | ||
defaultBranch: "main", | ||
tarballUrl: "https://github.com/antoine-coulon/skott/archive/main.zip" | ||
}); | ||
|
||
const { format, stream } = yield* _( | ||
pipe( | ||
Effect.map( | ||
fetcher.downloadTarball( | ||
"https://github.com/antoine-coulon/skott/archive/main.zip" | ||
), | ||
Option.getOrThrow | ||
) | ||
) | ||
); | ||
|
||
expect(format).to.equal("zip"); | ||
expect(stream).to.be.an.instanceOf(ReadableStream); | ||
}) | ||
); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
import * as S from "@effect/schema/Schema"; | ||
import { Effect, Option, flow, pipe } from "effect"; | ||
|
||
import { FetchPackageInformationError, type Fetcher } from "./definition.js"; | ||
|
||
interface GitHubRepositoryInformation { | ||
defaultBranch: string; | ||
} | ||
|
||
const GitHubSchema = S.struct({ | ||
default_branch: S.string, | ||
id: S.number | ||
}); | ||
|
||
function makeTarballUrl(branch: string, repositoryFullName: string) { | ||
return `https://github.com/${repositoryFullName}/archive/${branch}.zip`; | ||
} | ||
|
||
// eslint-disable-next-line func-style, @typescript-eslint/explicit-function-return-type | ||
export const githubFetcher: Fetcher<GitHubRepositoryInformation> = { | ||
fetchPackageInformation: (repositoryName) => | ||
pipe( | ||
Effect.tryPromise({ | ||
try: () => { | ||
const headers = process.env.GITHUB_TOKEN | ||
? { | ||
Authorization: `Bearer ${process.env.GITHUB_TOKEN}` | ||
} | ||
: {}; | ||
|
||
return fetch(`https://api.github.com/repos/${repositoryName}`, { | ||
headers | ||
} as any).then((response) => response.json()); | ||
}, | ||
catch: () => new FetchPackageInformationError() | ||
}), | ||
Effect.flatMap(flow(S.decodeUnknown(GitHubSchema), Effect.orDie)), | ||
Effect.map(({ default_branch, id }) => { | ||
return { | ||
id: id.toString(), | ||
defaultBranch: default_branch, | ||
tarballUrl: makeTarballUrl(default_branch, repositoryName) | ||
}; | ||
}) | ||
), | ||
downloadTarball: (tarballUrl) => | ||
Effect.promise(() => | ||
fetch(tarballUrl).then((response) => Option.fromNullable(response.body)) | ||
).pipe( | ||
Effect.map( | ||
Option.map((body) => { | ||
return { stream: body, format: "zip" }; | ||
}) | ||
) | ||
) | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,3 @@ | ||
export * from "./common.js"; | ||
export * from "./definition.js"; | ||
export * from "./npm.js"; | ||
export * from "./github.js"; |
92 changes: 58 additions & 34 deletions
92
packages/remote-tarball-fetcher/src/fetcher/npm.integration.spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,52 +1,76 @@ | ||
import { Readable } from "node:stream"; | ||
import { ReadableStream } from "node:stream/web"; | ||
|
||
import { expect } from "chai"; | ||
import { Effect, Option } from "effect"; | ||
|
||
import { npmFetcher } from "./npm.js"; | ||
|
||
function itEffect<A, E>( | ||
description: string, | ||
effect: Effect.Effect<A, E, never> | ||
) { | ||
it(description, () => effect.pipe(Effect.runPromise)); | ||
} | ||
|
||
describe("npm tarball fetcher", () => { | ||
describe("When fetching package information from the npm registry", () => { | ||
describe("When no version is provided", () => { | ||
it("should fetch both the latest version and the tarball of the latest version", async () => { | ||
const fetcher = npmFetcher; | ||
itEffect( | ||
"should fetch both the latest version and the tarball of the latest version", | ||
Effect.gen(function* gen(_) { | ||
const fetcher = npmFetcher; | ||
|
||
const packageInformation = await fetcher.fetchPackageInformation( | ||
"openforker" | ||
); | ||
const packageInformation = yield* _( | ||
fetcher.fetchPackageInformation("openforker") | ||
); | ||
|
||
expect(packageInformation).to.deep.equal({ | ||
latestVersion: "1.0.7", | ||
tarballUrl: | ||
"https://registry.npmjs.org/openforker/-/openforker-1.0.7.tgz" | ||
}); | ||
expect(packageInformation).to.deep.equal({ | ||
id: "1.0.7", | ||
latestVersion: "1.0.7", | ||
tarballUrl: | ||
"https://registry.npmjs.org/openforker/-/openforker-1.0.7.tgz" | ||
}); | ||
|
||
const tarball = await fetcher.downloadTarball( | ||
packageInformation.tarballUrl | ||
); | ||
const { stream } = yield* _( | ||
Effect.map( | ||
fetcher.downloadTarball(packageInformation.tarballUrl), | ||
Option.getOrThrow | ||
) | ||
); | ||
|
||
expect(tarball).to.be.an.instanceOf(Readable); | ||
}); | ||
expect(stream).to.be.an.instanceOf(ReadableStream); | ||
}) | ||
); | ||
}); | ||
|
||
describe("When a version is provided", () => { | ||
it("should fetch both the latest version and the tarball from the specified version", async () => { | ||
const fetcher = npmFetcher; | ||
|
||
const packageInformation = await fetcher.fetchPackageInformation( | ||
"openforker@1.0.5" | ||
); | ||
|
||
expect(packageInformation).to.deep.equal({ | ||
latestVersion: "1.0.7", | ||
tarballUrl: | ||
"https://registry.npmjs.org/openforker/-/openforker-1.0.5.tgz" | ||
}); | ||
|
||
const tarball = await fetcher.downloadTarball( | ||
packageInformation.tarballUrl | ||
); | ||
expect(tarball).to.be.an.instanceOf(Readable); | ||
}); | ||
itEffect( | ||
"should fetch both the latest version and the tarball from the specified version", | ||
Effect.gen(function* gen(_) { | ||
const fetcher = npmFetcher; | ||
|
||
const packageInformation = yield* _( | ||
fetcher.fetchPackageInformation("openforker@1.0.5") | ||
); | ||
|
||
expect(packageInformation).to.deep.equal({ | ||
id: "1.0.5", | ||
latestVersion: "1.0.7", | ||
tarballUrl: | ||
"https://registry.npmjs.org/openforker/-/openforker-1.0.5.tgz" | ||
}); | ||
|
||
const { format, stream } = yield* _( | ||
Effect.map( | ||
fetcher.downloadTarball(packageInformation.tarballUrl), | ||
Option.getOrThrow | ||
) | ||
); | ||
|
||
expect(format).to.equal("tar"); | ||
expect(stream).to.be.an.instanceOf(ReadableStream); | ||
}) | ||
); | ||
}); | ||
}); | ||
}); |
Oops, something went wrong.