test(runner): stage the build-once binary remotely
This commit is contained in:
parent
73a146e076
commit
7fe94196ba
|
|
@ -890,9 +890,6 @@ jobs:
|
|||
OPENROUTER_API_KEY: ${{ matrix.credentialName == 'OPENROUTER_API_KEY' && secrets.OPENROUTER_API_KEY || '' }}
|
||||
DAYTONA_API_KEY: ${{ matrix.environmentId == 'daytona' && secrets.DAYTONA_API_KEY || '' }}
|
||||
PAPERCLIP_E2E_DAYTONA_IMAGE: ${{ needs.daytona_image.outputs.image }}
|
||||
# Bind PRP identity to the exact build-once bytes that the server
|
||||
# stages into Daytona instead of a separately built image binary.
|
||||
PAPERCLIP_RUNNER_REMOTE_BINARY_PATH: ${{ github.workspace }}/packages/paperclip-runner/runner/target/debug/paperclip-runnerd
|
||||
PAPERCLIP_RUNNER_REMOTE_PROVIDER_PACK_PATH: ${{ github.workspace }}/packages/paperclip-runner/provider-pack
|
||||
PAPERCLIP_E2E_CAMPAIGN_ID: gha-${{ github.run_id }}-${{ github.run_attempt }}-${{ matrix.executionId }}
|
||||
run: pnpm test:e2e:runner -- --id "${{ matrix.executionId }}"
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ export function runnerE2EServerControlPaths(temporaryRoot: string) {
|
|||
}
|
||||
|
||||
/**
|
||||
* Local native cells use the debug binary produced by build:runner-binaries.
|
||||
* Native cells use the debug binary produced once by build:runner-binaries.
|
||||
* Preserve an explicit override for release builds and developer workflows.
|
||||
*/
|
||||
export function resolvePaperclipRunnerBinaryForHarness(
|
||||
|
|
@ -53,11 +53,7 @@ export function resolvePaperclipRunnerBinaryForHarness(
|
|||
): string | undefined {
|
||||
if (configuredPath?.trim()) return configuredPath;
|
||||
if (
|
||||
!executions.some(
|
||||
(execution) =>
|
||||
execution.environment.id === "local" &&
|
||||
execution.profile.generation === "native",
|
||||
)
|
||||
!executions.some((execution) => execution.profile.generation === "native")
|
||||
) {
|
||||
return undefined;
|
||||
}
|
||||
|
|
@ -73,6 +69,24 @@ export function resolvePaperclipRunnerBinaryForHarness(
|
|||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remote native cells stage the same controller-owned binary whose digest is
|
||||
* authorized by the PRP control plane. Local cells launch it directly.
|
||||
*/
|
||||
export function resolvePaperclipRemoteRunnerBinaryForHarness(
|
||||
executions: readonly MatrixExecution[],
|
||||
runnerBinary: string | undefined,
|
||||
): string | undefined {
|
||||
if (!runnerBinary) return undefined;
|
||||
return executions.some(
|
||||
(execution) =>
|
||||
execution.profile.generation === "native" &&
|
||||
execution.environment.expectedExecutionTarget.kind === "remote",
|
||||
)
|
||||
? runnerBinary
|
||||
: undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the environment inherited by the Paperclip server. Paid credentials
|
||||
* deliberately stay in the launcher/Playwright process and cross the server
|
||||
|
|
|
|||
|
|
@ -21,7 +21,10 @@ import { renderRunnerE2EDashboard } from "./dashboard.js";
|
|||
import { packageEvidence } from "./evidence.js";
|
||||
import { classifyFailure, shouldRetryFailure } from "./failure-classifier.js";
|
||||
import { buildRunnerCampaign } from "./history.js";
|
||||
import { resolvePaperclipRunnerBinaryForHarness } from "./harness-env.js";
|
||||
import {
|
||||
resolvePaperclipRemoteRunnerBinaryForHarness,
|
||||
resolvePaperclipRunnerBinaryForHarness,
|
||||
} from "./harness-env.js";
|
||||
import { assertEmbeddedDatabaseIsolation } from "./instance-isolation.js";
|
||||
import {
|
||||
assertSecretFree,
|
||||
|
|
@ -395,6 +398,10 @@ async function runAttempt(input: {
|
|||
betterAuthSecret,
|
||||
]);
|
||||
attemptSecrets = credentials;
|
||||
const runnerBinary = resolvePaperclipRunnerBinaryForHarness(
|
||||
executions,
|
||||
repositoryRoot,
|
||||
);
|
||||
const childEnv: NodeJS.ProcessEnv = {
|
||||
...process.env,
|
||||
PATH: providerPath,
|
||||
|
|
@ -407,10 +414,9 @@ async function runAttempt(input: {
|
|||
PAPERCLIP_RUNNER_E2E_PRIVATE_DIR: privateDir,
|
||||
PAPERCLIP_RUNNER_E2E_WORKSPACE: workspace,
|
||||
PAPERCLIP_RUNNER_E2E_SERVER_LOG: path.join(privateDir, "server.log"),
|
||||
PAPERCLIP_RUNNER_BINARY: resolvePaperclipRunnerBinaryForHarness(
|
||||
executions,
|
||||
repositoryRoot,
|
||||
),
|
||||
PAPERCLIP_RUNNER_BINARY: runnerBinary,
|
||||
PAPERCLIP_RUNNER_REMOTE_BINARY_PATH:
|
||||
resolvePaperclipRemoteRunnerBinaryForHarness(executions, runnerBinary),
|
||||
// Vite's optimized dependency cache embeds revision query strings. A
|
||||
// private per-attempt cache prevents an earlier cell or local rebuild
|
||||
// from producing `504 Outdated Optimize Dep` during browser bootstrap.
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import { classifyFailure, shouldRetryFailure } from "./failure-classifier.js";
|
|||
import {
|
||||
assertIsolatedServerEnvironment,
|
||||
buildPaperclipServerEnvironment,
|
||||
resolvePaperclipRemoteRunnerBinaryForHarness,
|
||||
resolvePaperclipRunnerBinaryForHarness,
|
||||
runnerE2EServerControlPaths,
|
||||
} from "./harness-env.js";
|
||||
|
|
@ -55,6 +56,9 @@ describe("runner E2E local binary resolution", () => {
|
|||
const localNativeExecution = runnerExecutionById(
|
||||
"core-compatibility.runner-codex.local.message-marker",
|
||||
);
|
||||
const remoteNativeExecution = runnerExecutionById(
|
||||
"core-compatibility.runner-acpx-claude.daytona.message-marker",
|
||||
);
|
||||
|
||||
it("uses the debug runner binary built by the E2E workflow", () => {
|
||||
expect(
|
||||
|
|
@ -82,6 +86,33 @@ describe("runner E2E local binary resolution", () => {
|
|||
),
|
||||
).toBe("/custom/paperclip-runnerd");
|
||||
});
|
||||
|
||||
it("uses and stages the same build-once binary for remote native cells", () => {
|
||||
const runnerBinary = resolvePaperclipRunnerBinaryForHarness(
|
||||
[remoteNativeExecution],
|
||||
"/repository",
|
||||
undefined,
|
||||
"linux",
|
||||
);
|
||||
expect(runnerBinary).toBe(
|
||||
path.join(
|
||||
"/repository",
|
||||
"packages/paperclip-runner/runner/target/debug/paperclip-runnerd",
|
||||
),
|
||||
);
|
||||
expect(
|
||||
resolvePaperclipRemoteRunnerBinaryForHarness(
|
||||
[remoteNativeExecution],
|
||||
runnerBinary,
|
||||
),
|
||||
).toBe(runnerBinary);
|
||||
expect(
|
||||
resolvePaperclipRemoteRunnerBinaryForHarness(
|
||||
[localNativeExecution],
|
||||
runnerBinary,
|
||||
),
|
||||
).toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
||||
describe("runner E2E server port allocation", () => {
|
||||
|
|
|
|||
|
|
@ -376,9 +376,6 @@ describe("public repository paid workflow security", () => {
|
|||
expect(testJob).toContain(
|
||||
"test -x packages/paperclip-runner/runner/target/debug/paperclip-runnerd",
|
||||
);
|
||||
expect(testJob).toContain(
|
||||
"PAPERCLIP_RUNNER_REMOTE_BINARY_PATH: ${{ github.workspace }}/packages/paperclip-runner/runner/target/debug/paperclip-runnerd",
|
||||
);
|
||||
expect(testJob).toContain(".payload.runnerSourceRevision == $revision");
|
||||
expect(workflow).toContain("Qualify local provider Node interpreter");
|
||||
expect(testJob).toContain(
|
||||
|
|
|
|||
Loading…
Reference in New Issue