mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-10-21 00:05:49 +02:00
Verify the installed Daytona plugin release identity
Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
1 parent
d3812f0326
commit
9085e28e67
5 files changed
+28
-5
No files matched your search
@@ -151,6 +151,10 @@ compiled plugin in its own installed dependency directory; the affected repeat
|
||||
passed. A separate credential-free public probe exposed a development-only Runner
|
||||
import in the installed configuration check. The production fix uses the vendored
|
||||
boundary, and the stronger public verifier and both installed smokes pass.
|
||||
The final fixture also checks the selected public plugin's release version and all
|
||||
compiled entries. A credential-free repeat against the exact installed plugin
|
||||
above passed; missing or mismatched version tests reject stale artifacts. This
|
||||
adds an admission check without changing the certified plugin or provider behavior.
|
||||
|
||||
Promotion checks passed: recursive typecheck, full build, token gates (1,129 files),
|
||||
Runner contract/replay checks, 164 focused Runner tests, executor/profile/runtime-mode coverage,
|
||||
|
||||
@@ -1609,6 +1609,15 @@ native binary overrides are removed from the server environment. Qualification
|
||||
admission is rejected, so this path requires production admission. Use the
|
||||
existing browser/API cases and encrypted company-secret fixture path.
|
||||
|
||||
Install the public `@paperclipai/plugin-daytona` package separately for a Daytona
|
||||
smoke. Set `PAPERCLIP_RUNNER_E2E_INSTALLED_DAYTONA_PLUGIN` to its absolute installed
|
||||
package directory when it has its own dependency root. The fixture checks its
|
||||
compiled entries and release version before provisioning. The version must match
|
||||
the installed CLI by default. If the release uses independent plugin versions,
|
||||
set `PAPERCLIP_RUNNER_E2E_INSTALLED_DAYTONA_PLUGIN_VERSION` to the exact plugin
|
||||
version in the release record. Record the plugin tarball SHA-256 with that version;
|
||||
do not substitute a workspace build or an older installed plugin.
|
||||
|
||||
For a diagnosed failure campaign, `PAPERCLIP_RUNNER_E2E_KEEP_FAILED_PRIVATE=1`
|
||||
retains the attempt's owner-only private directory after a failed case even
|
||||
when owned cleanup passed. This does not alter the case or cleanup outcome.
|
||||
|
||||
@@ -23,12 +23,17 @@ describe("ordinary installed release smoke", () => {
|
||||
mkdirSync(path.join(cliRoot, "dist"), { recursive: true }); mkdirSync(path.join(plugin, "dist"), { recursive: true });
|
||||
const cli = path.join(cliRoot, "dist/index.js"); writeFileSync(cli, "");
|
||||
writeFileSync(path.join(cliRoot, "package.json"), JSON.stringify({ name: "paperclipai", version: "0.0.0-verify" }));
|
||||
const manifest = { name: "@paperclipai/plugin-daytona", paperclipPlugin: { manifest: "./dist/manifest.js", worker: "./dist/worker.js" }, exports: { ".": { import: "./dist/index.js" } } };
|
||||
for (const file of ["manifest.js", "worker.js"]) writeFileSync(path.join(plugin, "dist", file), "");
|
||||
const manifest = { name: "@paperclipai/plugin-daytona", version: "0.0.0-verify", paperclipPlugin: { manifest: "./dist/manifest.js", worker: "./dist/worker.js" }, exports: { ".": { import: "./dist/index.js" } } };
|
||||
for (const file of ["manifest.js", "worker.js", "index.js"]) writeFileSync(path.join(plugin, "dist", file), "");
|
||||
writeFileSync(path.join(plugin, "package.json"), JSON.stringify(manifest));
|
||||
expect(installedReleaseDaytonaPlugin(cli)).toBe(plugin);
|
||||
expect(installedReleaseDaytonaPlugin(cli, plugin)).toBe(plugin);
|
||||
expect(() => installedReleaseDaytonaPlugin(cli, "relative/plugin")).toThrow("absolute");
|
||||
writeFileSync(path.join(plugin, "package.json"), JSON.stringify({ ...manifest, version: "0.0.0-stale" }));
|
||||
expect(() => installedReleaseDaytonaPlugin(cli, plugin)).toThrow("qualified release version 0.0.0-verify");
|
||||
expect(installedReleaseDaytonaPlugin(cli, plugin, "0.0.0-stale")).toBe(plugin);
|
||||
writeFileSync(path.join(plugin, "package.json"), JSON.stringify({ ...manifest, version: undefined }));
|
||||
expect(() => installedReleaseDaytonaPlugin(cli, plugin)).toThrow("qualified release version");
|
||||
writeFileSync(path.join(plugin, "package.json"), JSON.stringify({ ...manifest, exports: { ".": "./src/index.ts" } }));
|
||||
expect(() => installedReleaseDaytonaPlugin(cli)).toThrow("public compiled Daytona");
|
||||
writeFileSync(path.join(plugin, "package.json"), JSON.stringify(manifest));
|
||||
|
||||
@@ -14,8 +14,8 @@ export function installedReleaseLaunch(cliPath: string) {
|
||||
return { cli, cwd: root, args: [cli, "onboard", "--yes", "--run"], version: manifest.version };
|
||||
}
|
||||
|
||||
/** Install the public plugin from the same consumer, without a workspace loader. */
|
||||
export function installedReleaseDaytonaPlugin(cliPath: string, installedPluginPath?: string): string {
|
||||
/** Verify the selected public plugin belongs to the release being qualified. */
|
||||
export function installedReleaseDaytonaPlugin(cliPath: string, installedPluginPath?: string, expectedVersion?: string): string {
|
||||
const cli = installedReleaseLaunch(cliPath);
|
||||
if (installedPluginPath && !path.isAbsolute(installedPluginPath)) throw new Error("Installed Daytona plugin path must be absolute");
|
||||
const plugin = realpathSync(installedPluginPath ?? path.join(path.dirname(cli.cwd), "@paperclipai/plugin-daytona"));
|
||||
@@ -26,8 +26,13 @@ export function installedReleaseDaytonaPlugin(cliPath: string, installedPluginPa
|
||||
manifest.exports?.["."]?.import !== "./dist/index.js") {
|
||||
throw new Error("Installed release requires the public compiled Daytona plugin package");
|
||||
}
|
||||
const releaseVersion = expectedVersion ?? cli.version;
|
||||
if (!releaseVersion || manifest.version !== releaseVersion) {
|
||||
throw new Error(`Installed Daytona plugin must match qualified release version ${releaseVersion}`);
|
||||
}
|
||||
realpathSync(path.join(plugin, "dist/manifest.js"));
|
||||
realpathSync(path.join(plugin, "dist/worker.js"));
|
||||
realpathSync(path.join(plugin, "dist/index.js"));
|
||||
return plugin;
|
||||
}
|
||||
|
||||
|
||||
@@ -117,7 +117,7 @@ export async function setupLiveFixtures(input: {
|
||||
async setup() {
|
||||
return api.post<PluginRecord>("/api/plugins/install", {
|
||||
packageName: process.env.PAPERCLIP_RUNNER_E2E_INSTALLED_CLI
|
||||
? installedReleaseDaytonaPlugin(process.env.PAPERCLIP_RUNNER_E2E_INSTALLED_CLI, process.env.PAPERCLIP_RUNNER_E2E_INSTALLED_DAYTONA_PLUGIN)
|
||||
? installedReleaseDaytonaPlugin(process.env.PAPERCLIP_RUNNER_E2E_INSTALLED_CLI, process.env.PAPERCLIP_RUNNER_E2E_INSTALLED_DAYTONA_PLUGIN, process.env.PAPERCLIP_RUNNER_E2E_INSTALLED_DAYTONA_PLUGIN_VERSION)
|
||||
: path.resolve(
|
||||
import.meta.dirname,
|
||||
"../../packages/plugins/sandbox-providers/daytona",
|
||||
|
||||
Reference in new issue
Block a user