@alchemy.run/pkg 0.0.0-placeholder → 2.0.0-beta.78
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -0
- package/NOTICE +5 -0
- package/README.md +117 -0
- package/dist/Manifest.d.ts +107 -0
- package/dist/Manifest.d.ts.map +1 -0
- package/dist/Manifest.js +58 -0
- package/dist/Manifest.js.map +1 -0
- package/dist/Protocol.d.ts +186 -0
- package/dist/Protocol.d.ts.map +1 -0
- package/dist/Protocol.js +115 -0
- package/dist/Protocol.js.map +1 -0
- package/dist/Registry/Bindings.d.ts +134 -0
- package/dist/Registry/Bindings.d.ts.map +1 -0
- package/dist/Registry/Bindings.js +92 -0
- package/dist/Registry/Bindings.js.map +1 -0
- package/dist/Registry/GitHub.d.ts +96 -0
- package/dist/Registry/GitHub.d.ts.map +1 -0
- package/dist/Registry/GitHub.js +226 -0
- package/dist/Registry/GitHub.js.map +1 -0
- package/dist/Registry/Handler.d.ts +53 -0
- package/dist/Registry/Handler.d.ts.map +1 -0
- package/dist/Registry/Handler.js +375 -0
- package/dist/Registry/Handler.js.map +1 -0
- package/dist/Registry/KVCache.d.ts +24 -0
- package/dist/Registry/KVCache.d.ts.map +1 -0
- package/dist/Registry/KVCache.js +42 -0
- package/dist/Registry/KVCache.js.map +1 -0
- package/dist/Registry/Sweep.d.ts +12 -0
- package/dist/Registry/Sweep.d.ts.map +1 -0
- package/dist/Registry/Sweep.js +69 -0
- package/dist/Registry/Sweep.js.map +1 -0
- package/dist/Registry/Tags.d.ts +49 -0
- package/dist/Registry/Tags.d.ts.map +1 -0
- package/dist/Registry/Tags.js +80 -0
- package/dist/Registry/Tags.js.map +1 -0
- package/dist/Registry.d.ts +378 -0
- package/dist/Registry.d.ts.map +1 -0
- package/dist/Registry.js +119 -0
- package/dist/Registry.js.map +1 -0
- package/dist/cli/bin.d.ts +18 -0
- package/dist/cli/bin.d.ts.map +1 -0
- package/dist/cli/bin.js +33 -0
- package/dist/cli/bin.js.map +1 -0
- package/dist/cli/pack.d.ts +169 -0
- package/dist/cli/pack.d.ts.map +1 -0
- package/dist/cli/pack.js +447 -0
- package/dist/cli/pack.js.map +1 -0
- package/dist/cli/publish.d.ts +33 -0
- package/dist/cli/publish.d.ts.map +1 -0
- package/dist/cli/publish.js +76 -0
- package/dist/cli/publish.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -0
- package/migrations/0001_init.sql +19 -0
- package/package.json +89 -1
- package/src/Manifest.ts +76 -0
- package/src/Protocol.ts +163 -0
- package/src/Registry/Bindings.ts +134 -0
- package/src/Registry/GitHub.ts +365 -0
- package/src/Registry/Handler.ts +549 -0
- package/src/Registry/KVCache.ts +68 -0
- package/src/Registry/Sweep.ts +117 -0
- package/src/Registry/Tags.ts +117 -0
- package/src/Registry.ts +197 -0
- package/src/cli/bin.ts +101 -0
- package/src/cli/pack.ts +603 -0
- package/src/cli/publish.ts +129 -0
- package/src/index.ts +5 -0
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import * as Config from "effect/Config";
|
|
2
|
+
import * as Console from "effect/Console";
|
|
3
|
+
import * as Data from "effect/Data";
|
|
4
|
+
import * as Effect from "effect/Effect";
|
|
5
|
+
import * as FileSystem from "effect/FileSystem";
|
|
6
|
+
import * as Path from "effect/Path";
|
|
7
|
+
import * as Schema from "effect/Schema";
|
|
8
|
+
import * as HttpApiClient from "effect/unstable/httpapi/HttpApiClient";
|
|
9
|
+
import { MANIFEST_FILE, ManifestJson, type Manifest } from "../Manifest.ts";
|
|
10
|
+
import { PkgApi, type TarballRef } from "../Protocol.ts";
|
|
11
|
+
|
|
12
|
+
export class PublishError extends Data.TaggedError("PublishError")<{
|
|
13
|
+
readonly message: string;
|
|
14
|
+
}> {}
|
|
15
|
+
|
|
16
|
+
export interface PublishOptions {
|
|
17
|
+
readonly cwd: string;
|
|
18
|
+
readonly dir: string;
|
|
19
|
+
readonly registry: string;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* The GitHub Actions run this job belongs to, from the runner's environment.
|
|
24
|
+
*/
|
|
25
|
+
const currentRun = Effect.gen(function* () {
|
|
26
|
+
const repo = yield* Config.String("GITHUB_REPOSITORY");
|
|
27
|
+
const runId = yield* Config.Int("GITHUB_RUN_ID");
|
|
28
|
+
const attempt = yield* Config.Int("GITHUB_RUN_ATTEMPT").pipe(
|
|
29
|
+
Config.withDefault(1),
|
|
30
|
+
);
|
|
31
|
+
return { repo, runId, attempt };
|
|
32
|
+
}).pipe(
|
|
33
|
+
Effect.mapError(
|
|
34
|
+
() =>
|
|
35
|
+
new PublishError({
|
|
36
|
+
message: "pkg publish must run inside a GitHub Actions job",
|
|
37
|
+
}),
|
|
38
|
+
),
|
|
39
|
+
);
|
|
40
|
+
|
|
41
|
+
/** Render a registry or transport failure as a `PublishError`. */
|
|
42
|
+
const failed =
|
|
43
|
+
(what: string) => (e: { readonly _tag: string; readonly message?: string }) =>
|
|
44
|
+
new PublishError({
|
|
45
|
+
message: `${what}: ${e.message ? `${e._tag}: ${e.message}` : e._tag}`,
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Publish a `pkg pack` directory from the current GitHub Actions job. The
|
|
50
|
+
* workflow must first have uploaded the manifest as an artifact of the run
|
|
51
|
+
* under the name `pkg pack` printed; the registry verifies that artifact
|
|
52
|
+
* through GitHub, then either reports the tarballs it lacks, which are
|
|
53
|
+
* uploaded before trying again, or writes the tags.
|
|
54
|
+
*/
|
|
55
|
+
export const publish = Effect.fn("publish")(function* (
|
|
56
|
+
options: PublishOptions,
|
|
57
|
+
) {
|
|
58
|
+
const fs = yield* FileSystem.FileSystem;
|
|
59
|
+
const path = yield* Path.Path;
|
|
60
|
+
const registry = options.registry.replace(/\/+$/, "");
|
|
61
|
+
const run = yield* currentRun;
|
|
62
|
+
const client = yield* HttpApiClient.make(PkgApi, { baseUrl: registry });
|
|
63
|
+
|
|
64
|
+
const dir = path.resolve(options.cwd, options.dir);
|
|
65
|
+
const manifestText = yield* fs.readFileString(path.join(dir, MANIFEST_FILE));
|
|
66
|
+
const manifest =
|
|
67
|
+
yield* Schema.decodeUnknownEffect(ManifestJson)(manifestText);
|
|
68
|
+
if (manifest.registry !== registry) {
|
|
69
|
+
return yield* new PublishError({
|
|
70
|
+
message: `artifact was packed for ${manifest.registry}, not ${registry}`,
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const upload = (pkg: Manifest["packages"][number]) =>
|
|
75
|
+
Effect.gen(function* () {
|
|
76
|
+
const bytes = yield* fs.readFile(path.join(dir, pkg.file));
|
|
77
|
+
const result = yield* client.Registry.uploadTarball({
|
|
78
|
+
params: { name: pkg.name, sha256: pkg.sha256 },
|
|
79
|
+
query: run,
|
|
80
|
+
payload: bytes,
|
|
81
|
+
}).pipe(Effect.mapError(failed(`upload ${pkg.name}`)));
|
|
82
|
+
yield* Console.log(
|
|
83
|
+
`${result.uploaded ? "Uploaded" : "Reused"} ${pkg.name} (${pkg.sha256.slice(0, 12)}, ${pkg.size} bytes)`,
|
|
84
|
+
);
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
const uploadMissing = (missing: ReadonlyArray<TarballRef>) => {
|
|
88
|
+
const wanted = new Set(missing.map((ref) => `${ref.name}@${ref.sha256}`));
|
|
89
|
+
return Console.log(
|
|
90
|
+
`${missing.length} of ${manifest.packages.length} tarball(s) to upload`,
|
|
91
|
+
).pipe(
|
|
92
|
+
Effect.andThen(
|
|
93
|
+
Effect.forEach(
|
|
94
|
+
manifest.packages.filter((pkg) =>
|
|
95
|
+
wanted.has(`${pkg.name}@${pkg.sha256}`),
|
|
96
|
+
),
|
|
97
|
+
upload,
|
|
98
|
+
{ concurrency: 4, discard: true },
|
|
99
|
+
),
|
|
100
|
+
),
|
|
101
|
+
);
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
const attempt = client.Registry.publish({
|
|
105
|
+
payload: { run, manifest: manifestText },
|
|
106
|
+
});
|
|
107
|
+
const published = yield* attempt.pipe(
|
|
108
|
+
// The first answer is usually the tarballs to upload; publish once more
|
|
109
|
+
// after uploading them.
|
|
110
|
+
Effect.catchTag("MissingTarballs", (e) =>
|
|
111
|
+
Effect.andThen(uploadMissing(e.missing), attempt),
|
|
112
|
+
),
|
|
113
|
+
Effect.catchTag(
|
|
114
|
+
"MissingTarballs",
|
|
115
|
+
(e) =>
|
|
116
|
+
new PublishError({
|
|
117
|
+
message: `registry still reports missing tarballs after upload: ${e.missing.map((ref) => ref.name).join(", ")}`,
|
|
118
|
+
}),
|
|
119
|
+
),
|
|
120
|
+
Effect.mapError((e) =>
|
|
121
|
+
e._tag === "PublishError" ? e : failed("publish")(e),
|
|
122
|
+
),
|
|
123
|
+
);
|
|
124
|
+
|
|
125
|
+
for (const pkg of published.packages) {
|
|
126
|
+
yield* Console.log(`${pkg.name}: ${pkg.url} [${pkg.tags.join(", ")}]`);
|
|
127
|
+
}
|
|
128
|
+
return published;
|
|
129
|
+
});
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
// The shared surface between the CLI and the registry Worker. The Worker
|
|
2
|
+
// itself lives on `@alchemy.run/pkg/Registry` so that importing this module
|
|
3
|
+
// never drags Cloudflare or GitHub runtime code into a CLI process.
|
|
4
|
+
export * from "./Manifest.ts";
|
|
5
|
+
export * from "./Protocol.ts";
|